Skip to content

Instantly share code, notes, and snippets.

@lygaret
Last active June 9, 2022 08:02
Show Gist options
  • Select an option

  • Save lygaret/117441fc5236de9f7d54b76894d69dec to your computer and use it in GitHub Desktop.

Select an option

Save lygaret/117441fc5236de9f7d54b76894d69dec to your computer and use it in GitHub Desktop.

Revisions

  1. lygaret revised this gist Jun 9, 2022. 1 changed file with 6 additions and 0 deletions.
    6 changes: 6 additions & 0 deletions .yardopts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,6 @@
    -m markdown
    --private
    --protected
    --embed-mixins
    --default-return void
    **/*.rb
  2. lygaret revised this gist Jun 9, 2022. 2 changed files with 34 additions and 1 deletion.
    2 changes: 1 addition & 1 deletion string-inquirer.rb
    Original file line number Diff line number Diff line change
    @@ -51,7 +51,7 @@ def method_missing(name, ...)
    end

    def respond_to_missing?(name, incl_private = false)
    predicate_value(name.to_s) ? super : true
    predicate_value(name.to_s) ? true : super
    end

    end
    33 changes: 33 additions & 0 deletions string-inquirer.test.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,33 @@
    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

  3. lygaret revised this gist Jun 9, 2022. 2 changed files with 15 additions and 6 deletions.
    12 changes: 9 additions & 3 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -1,8 +1,14 @@
    ---
    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 properly handling `respond_to_missing`,
    and instantiate as a mixin to a string's `singleton_class`, rather than as a subclass.
    Basically what Rails does in ActiveSupport, but packaged as a tiny gem.

    ## Usage

    @@ -20,4 +26,4 @@ runtime_mode = Accidental::StringInquirer.upgrade runtime_mode

    "development".development? #=> NoMethodError
    runtime_mode.development? #=> true
    ```
    ```
    9 changes: 6 additions & 3 deletions string-inquirer.gemspec
    Original file line number Diff line number Diff line change
    @@ -1,10 +1,13 @@
    require "yaml"

    header = YAML.safe_load_file("readme.md")
    Gem::Specification.new do |spec|
    spec.name = "string-inquirer"
    spec.version = "0.0.1"
    spec.name = header["name"]
    spec.version = header["version"]
    spec.authors = ["Jon Raphaelson"]
    spec.email = ["jon@accidental.cc"]

    spec.summary = %q{simple mixin for string equality predicates}
    spec.summary = header["summary"]
    spec.license = "MIT"

    spec.files = Dir.glob("**/*.rb", base: __dir__)
  4. lygaret revised this gist Jun 9, 2022. 1 changed file with 23 additions and 0 deletions.
    23 changes: 23 additions & 0 deletions readme.md
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,23 @@
    Adds methods to string which allows checking for string equality through
    arbitrary predicate methods.

    Basically what Rails does in ActiveSupport, but properly handling `respond_to_missing`,
    and instantiate as a mixin to a string's `singleton_class`, rather than as a subclass.

    ## Usage

    Add this repo to your `Gemfile`:

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

    Then in your code:

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

    "development".development? #=> NoMethodError
    runtime_mode.development? #=> true
    ```
  5. lygaret revised this gist Jun 9, 2022. No changes.
  6. lygaret revised this gist Jun 9, 2022. 2 changed files with 6 additions and 6 deletions.
    2 changes: 1 addition & 1 deletion string-inquiry.gemspec → string-inquirer.gemspec
    Original file line number Diff line number Diff line change
    @@ -1,5 +1,5 @@
    Gem::Specification.new do |spec|
    spec.name = "string-inquiry"
    spec.name = "string-inquirer"
    spec.version = "0.0.1"
    spec.authors = ["Jon Raphaelson"]
    spec.email = ["jon@accidental.cc"]
    10 changes: 5 additions & 5 deletions string-inquiry.rb → string-inquirer.rb
    Original file line number Diff line number Diff line change
    @@ -4,7 +4,7 @@ module Accidental
    #
    # @example
    # runtime_mode = "deploy".freeze
    # runtime_mode = Accidental::StringInquiry.upgrade runtime_mode
    # runtime_mode = Accidental::StringInquirer.upgrade runtime_mode
    #
    # # predicate methods check for string equality
    # runtime_mode.deploy? #=> true
    @@ -13,17 +13,17 @@ module Accidental
    # # still a string, we add methods to the singleton class
    # runtime_mode.class #=> String
    # runtime_mode == "deploy" #=> true
    module StringInquiry
    module StringInquirer

    # matches predicate looking methods
    INQUIRER_FORMAT = /^(.+)\?$/

    # a duplicate of the given string, with StringInquiry functionality mixed in.
    # 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 StringInquiry }
    str.dup.tap { _1.singleton_class.include StringInquirer }
    end

    # @param name [String] the method name to turn into a predicate check
    @@ -39,7 +39,7 @@ def predicate_value(name)
    # If the missing method is _not_ a predicate, keep going up the chain.
    #
    # @example
    # foo = StringInquiry.upgrade "foo"
    # foo = StringInquirer.upgrade "foo"
    # "foo".development #=> NoMethodError
    # "foo".development? #=> false ("foo" != "development")
    # "foo".foo? #=> true ("foo" == "foo")
  7. lygaret revised this gist Jun 9, 2022. No changes.
  8. lygaret created this gist Jun 9, 2022.
    12 changes: 12 additions & 0 deletions string-inquiry.gemspec
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,12 @@
    Gem::Specification.new do |spec|
    spec.name = "string-inquiry"
    spec.version = "0.0.1"
    spec.authors = ["Jon Raphaelson"]
    spec.email = ["jon@accidental.cc"]

    spec.summary = %q{simple mixin for string equality predicates}
    spec.license = "MIT"

    spec.files = Dir.glob("**/*.rb", base: __dir__)
    spec.require_paths = ["."]
    end
    59 changes: 59 additions & 0 deletions string-inquiry.rb
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,59 @@
    module Accidental
    # Adds methods to strings which allows checking for string equality through
    # arbitrary predicate methods;
    #
    # @example
    # runtime_mode = "deploy".freeze
    # runtime_mode = Accidental::StringInquiry.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 StringInquiry

    # matches predicate looking methods
    INQUIRER_FORMAT = /^(.+)\?$/

    # a duplicate of the given string, with StringInquiry 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 StringInquiry }
    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 = StringInquiry.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) ? super : true
    end

    end
    end