Last active
November 25, 2016 23:34
-
-
Save BFalkner/410373 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| require "continuation" | |
| module ActivePattern | |
| module CaseEqlTrue | |
| def ===(param) | |
| true | |
| end | |
| end | |
| class CaseEqlWrapper | |
| undef_method(*(instance_methods - %w*__id__ __send__*)) | |
| def initialize(value) | |
| @value = value | |
| end | |
| def method_missing(*args, &block) | |
| @value.send *args, &block | |
| end | |
| def ===(param) | |
| true | |
| end | |
| end | |
| class MatchArray < Array | |
| def ===(param) | |
| true | |
| end | |
| end | |
| class Pattern | |
| def self.build(&block) | |
| callcc do |cont| | |
| Pattern.new(cont, &block) | |
| end | |
| end | |
| def initialize(cont, &block) | |
| @cont = cont | |
| @block = block | |
| end | |
| def ===(param) | |
| falsey = Object.new | |
| result = @block.call(param, falsey) | |
| return false if result == falsey | |
| begin | |
| result.extend(CaseEqlTrue) | |
| @cont.call(result) | |
| rescue TypeError # frozen or singleton | |
| @cont.call(CaseEqlWrapper.new(result)) | |
| end | |
| end | |
| end | |
| class MultiPattern < Array | |
| def self.build(&block) | |
| callcc do |cont| | |
| MultiPattern.new(cont, &block) | |
| end | |
| end | |
| def initialize(cont, &block) | |
| @cont = cont | |
| @block = block | |
| end | |
| def ===(param) | |
| falsey = Object.new | |
| result = @block.call(param, falsey) | |
| return false if result == falsey | |
| @cont.call(MatchArray.new(result)) | |
| end | |
| end | |
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| def integer? | |
| ActivePattern::Pattern.build do |value, pass| | |
| if value.is_a? Integer | |
| value | |
| elsif value.is_a? String | |
| /\A[-+]?\d+\z/ === value ? value.to_i : pass | |
| else | |
| pass | |
| end | |
| end | |
| end | |
| def float? | |
| ActivePattern::Pattern.build do |value, pass| | |
| if value.is_a? Float | |
| value | |
| elsif value.is_a? String | |
| /\A[-+]?\d+\.\d+\z/ === value ? value.to_f : pass | |
| else | |
| pass | |
| end | |
| end | |
| end | |
| def cast_value(value) | |
| case value | |
| when n = integer? then n | |
| when n = float? then n | |
| else nil | |
| end | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment