gem - string-inquirer

Jonathan Raphaelson
2022-06-09T05:58:26Z

.yardopts

| -m markdown
| --private
| --protected
| --embed-mixins
| --default-return void
| **/*.rb

readme.md

name | string-inquirer
version | 0.0.1
summary | a small, simple mixin for string equality predicates

Adds methods to string which allows checking for string equality through arbitrary predicate methods.

Basically what Rails does in ActiveSupport, but packaged as a tiny gem.

Usage

Add this repo to your Gemfile:

gem "string-inquirer", "~> 0", git: "https://gist.github.com/117441fc5236de9f7d54b76894d69dec.git"

Then in your code:

runtime_mode = "development".freeze
runtime_mode = Accidental::StringInquirer.upgrade runtime_mode

"development".development? #=> NoMethodError
runtime_mode.development? #=> true

string-inquirer.gemspec

| require "yaml"
|
| header = YAML.safe_load_file("readme.md")
| Gem::Specification.new do |spec|
| spec.name = header["name"]
| spec.version = header["version"]
| spec.authors = ["Jon Raphaelson"]
| spec.email = ["jon@accidental.cc"]
|
| spec.summary = header["summary"]
| spec.license = "MIT"
|
| spec.files = Dir.glob("**/*.rb", base: __dir__)
| spec.require_paths = ["."]
| end

string-inquirer.rb

| module Accidental
| # Adds methods to strings which allows checking for string equality through
| # arbitrary predicate methods;
| #
| # @example
| # runtime_mode = "deploy".freeze
| # runtime_mode = Accidental::StringInquirer.upgrade runtime_mode
| #
| # # predicate methods check for string equality
| # runtime_mode.deploy? #=> true
| # runtime_mode.development? #=> false
| #
| # # still a string, we add methods to the singleton class
| # runtime_mode.class #=> String
| # runtime_mode == "deploy" #=> true
| module StringInquirer
|
| # matches predicate looking methods
| INQUIRER_FORMAT = /^(.+)\?$/
|
| # a duplicate of the given string, with StringInquirer functionality mixed in.
| # @return [String]
| def self.upgrade(str)
| raise ArgumentError, "must be a string!" unless str.is_a? String
|
| str.dup.tap { _1.singleton_class.include StringInquirer }
| end
|
| # @param name [String] the method name to turn into a predicate check
| # @return [String, nil] the string to check, or nil if not a predicate
| def predicate_value(name)
| match = INQUIRER_FORMAT.match name
| match&.[](1)
| end
|
| # If the name of the missing method is a predicate (per {INQUIRER_FORMAT}),
| # the return value will be the string equality of the method name with self.
| #
| # If the missing method is _not_ a predicate, keep going up the chain.
| #
| # @example
| # foo = StringInquirer.upgrade "foo"
| # "foo".development #=> NoMethodError
| # "foo".development? #=> false ("foo" != "development")
| # "foo".foo? #=> true ("foo" == "foo")
| def method_missing(name, ...)
| value = predicate_value(name.to_s)
| return super(name, ...) if value.nil?
|
| eql? value
| end
|
| def respond_to_missing?(name, incl_private = false)
| predicate_value(name.to_s) ? true : super
| end
|
| end
| end
|

string-inquirer.test.rb

| require 'minitest/autorun'
| require './string-inquirer'
|
| describe Accidental::StringInquirer do
| before do
| @mode = "development"
| @mode = Accidental::StringInquirer.upgrade(@mode)
| end
|
| it "should still be a string" do
| assert_kind_of String, @mode
| end
|
| it "should respond to arbitrary predicates" do
| assert_respond_to @mode, :whatever?
| end
|
| it "true when predicate matches the string" do
| assert @mode.development?
| end
|
| it "false when predicate doesn't match the string" do
| refute @mode.whatever?
| end
|
| it "can hand out a method" do
| meth = @mode.method(:development?)
|
| assert_kind_of Method, meth
| assert meth.call
| end
| end
|