filigree 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 178a6b1f4c1c7e4fa5572856e84f8e42e61ef423
4
- data.tar.gz: 0b4d734851d85411da754286fbe7562dd894e8a7
3
+ metadata.gz: 7c7696d87311fb00c3506b41c1f8b50e944bb63b
4
+ data.tar.gz: eb00162a46ccfbb5742e56498233f44e36b5d760
5
5
  SHA512:
6
- metadata.gz: 37ed52f1a1780895bfdb255625f9edd5a649c96595395851a1d99ae79ba695e7f45f4e5d443452342ce3aa77db665b24abf9a71c67579233bf806ce3177e41c0
7
- data.tar.gz: 67ded0ee569137d4dd0b00d99e753af2db406beff41f8a6994b76bfff52521b4b7f08316c4d3ff3128f0180b7b1cea91aa2c1cbd1e7900278a2c46d5e7ae242b
6
+ metadata.gz: 783be7b5c305016fe61287d6c41c7f49f7e15b380cf199cfcf0633ef5e2b4cd073cae6608879655d65d134b69554bf3d9c24195fccc908d6b8dd4a14c1425e34
7
+ data.tar.gz: 98e5f988abc878f3f6da8e48faf8e29b547488a69f76bd3124d6541d0f321a87e7490c9a2f275068ca07dc91d35178cf090f91699ab4ab2ebcc5bc1f81f8b604
data/README.md CHANGED
@@ -164,11 +164,7 @@ Filigree's implementation of the visitor pattern is built on the pattern matchin
164
164
  ```Ruby
165
165
  class Binary < Struct.new(:x, :y)
166
166
  extend Filigree::Destructurable
167
- include Filigree::Visitable
168
-
169
- def children
170
- [x, y]
171
- end
167
+ include Filigree::Visitor
172
168
 
173
169
  def destructure(_)
174
170
  [x, y]
data/Rakefile CHANGED
@@ -1,15 +1,19 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
2
- # Project: Filigree
3
- # Date: 2013/4/19
4
- # Description: Filigree's Rakefile.
1
+ # Author: Chris Wailes <chris.wailes@gmail.com>
2
+ # Project: Filigree
3
+ # Date: 2013/4/19
4
+ # Description: Filigree's Rakefile.
5
5
 
6
6
  ############
7
7
  # Requires #
8
8
  ############
9
9
 
10
+ # Add the Filigree source directory to the load path.
11
+ lib_dir = File.expand_path("./lib/", File.dirname(__FILE__))
12
+ $LOAD_PATH << lib_dir unless $LOAD_PATH.include?(lib_dir)
13
+
10
14
  # Filigree
11
- require File.expand_path("../lib/filigree/request_file", __FILE__)
12
- require File.expand_path("../lib/filigree/version", __FILE__)
15
+ require 'filigree/request_file'
16
+ require 'filigree/version'
13
17
 
14
18
  ###########
15
19
  # Bundler #
@@ -36,12 +40,12 @@ end
36
40
  # Flog #
37
41
  ########
38
42
 
39
- request_file('flog_cli', 'Flog is not installed.') do
43
+ request_file('flog_task', 'Flog is not installed.') do
40
44
  desc 'Analyze code complexity with Flog'
41
- task :flog do
42
- whip = FlogCLI.new
43
- whip.flog('lib')
44
- whip.report
45
+ FlogTask.new do |t|
46
+ t.dirs = ['lib']
47
+ t.method = :max_method
48
+ t.verbose = true
45
49
  end
46
50
  end
47
51
 
@@ -94,7 +98,7 @@ request_file('yard', 'Yard is not installed.') do
94
98
  '-M', 'redcarpet',
95
99
  '--private'
96
100
  ]
97
-
101
+
98
102
  t.files = Dir['lib/**/*.rb']
99
103
  end
100
104
  end
@@ -1,4 +1,4 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
1
+ # Author: Chris Wailes <chris.wailes+filigree@gmail.com>
2
2
  # Project: Filigree
3
3
  # Date: 2013/4/19
4
4
  # Description: The root file for the Filigree project.
@@ -1,4 +1,4 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
1
+ # Author: Chris Wailes <chris.wailes+filigree@gmail.com>
2
2
  # Project: Filigree
3
3
  # Date: 2013/4/19
4
4
  # Description: An implementation of an AbstractClass module.
@@ -69,7 +69,7 @@ module Filigree
69
69
  #
70
70
  # @raise [AbstractClassError]
71
71
  def new(*args)
72
- if @abstract_class == self
72
+ if self.instance_variable_defined?(:'@abstract_class') and @abstract_class == self
73
73
  raise AbstractClassError, self.name
74
74
  else
75
75
  super
@@ -1,7 +1,7 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
2
- # Project: Filigree
3
- # Date: 2013/05/14
4
- # Description: Simple application framework.
1
+ # Author: Chris Wailes <chris.wailes+filigree@gmail.com>
2
+ # Project: Filigree
3
+ # Date: 2013/05/14
4
+ # Description: Simple application framework.
5
5
 
6
6
  ############
7
7
  # Requires #
@@ -36,8 +36,6 @@ module Filigree
36
36
  #############
37
37
 
38
38
  REQUIRED_METHODS = [
39
- :kill,
40
- :pause,
41
39
  :resume,
42
40
  :run,
43
41
  :stop
@@ -59,10 +57,7 @@ module Filigree
59
57
  Signal.trap('QUIT') { self.stop }
60
58
  Signal.trap('TERM') { self.stop }
61
59
 
62
- Signal.trap('KILL') { self.kill }
63
-
64
60
  Signal.trap('CONT') { self.resume }
65
- Signal.trap('STOP') { self.pause }
66
61
  end
67
62
 
68
63
  #################
@@ -1,7 +1,7 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
2
- # Project: Filigree
3
- # Date: 2013/05/04
4
- # Description: Class extensions for dealing with integers and booleans.
1
+ # Author: Chris Wailes <chris.wailes+filigree@gmail.com>
2
+ # Project: Filigree
3
+ # Date: 2013/05/04
4
+ # Description: Class extensions for dealing with integers and booleans.
5
5
 
6
6
  ############
7
7
  # Requires #
@@ -15,26 +15,29 @@
15
15
  # Classes and Modules #
16
16
  #######################
17
17
 
18
- # Extra boolean support for the Integer class.
19
- class Integer
20
- # @return [Boolean] This Integer as a Boolean value.
21
- def to_bool
22
- self != 0
18
+ module Filigree
19
+
20
+ # Extra boolean support for the Integer class.
21
+ refine Integer do
22
+ # @return [Boolean] This Integer as a Boolean value.
23
+ def to_bool
24
+ self != 0
25
+ end
23
26
  end
24
- end
25
27
 
26
- # Extra boolean support for the TrueClass class.
27
- class TrueClass
28
- # @return [1]
29
- def to_i
30
- 1
28
+ # Extra boolean support for the TrueClass class.
29
+ refine TrueClass do
30
+ # @return [1]
31
+ def to_i
32
+ 1
33
+ end
31
34
  end
32
- end
33
35
 
34
- # Extra boolean support for the FalseClass class.
35
- class FalseClass
36
- # @return [0]
37
- def to_i
38
- 0
36
+ # Extra boolean support for the FalseClass class.
37
+ refine FalseClass do
38
+ # @return [0]
39
+ def to_i
40
+ 0
41
+ end
39
42
  end
40
43
  end
@@ -1,7 +1,7 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
2
- # Project: Filigree
3
- # Date: 2013/05/04
4
- # Description: Class extensions for the Class class.
1
+ # Author: Chris Wailes <chris.wailes+filigree@gmail.com>
2
+ # Project: Filigree
3
+ # Date: 2013/05/04
4
+ # Description: Class extensions for the Class class.
5
5
 
6
6
  ############
7
7
  # Requires #
@@ -16,33 +16,36 @@ require 'filigree/types'
16
16
  # Classes and Modules #
17
17
  #######################
18
18
 
19
- class Class
20
- # Checks for module inclusion.
21
- #
22
- # @param [Module] mod Module to check the inclusion of.
23
- #
24
- # @return [Boolean] If the module was included
25
- def includes_module?(mod)
26
- self.included_modules.include?(mod)
27
- end
19
+ module Filigree
28
20
 
29
- # @return [String] Name of class without the namespace.
30
- def short_name
31
- self.name.split('::').last
32
- end
21
+ refine Class do
22
+ # Checks for module inclusion.
23
+ #
24
+ # @param [Module] mod Module to check the inclusion of.
25
+ #
26
+ # @return [Boolean] If the module was included
27
+ def includes_module?(mod)
28
+ self.included_modules.include?(mod)
29
+ end
30
+
31
+ # @return [String] Name of class without the namespace.
32
+ def short_name
33
+ self.name.split('::').last
34
+ end
33
35
 
34
- # Checks to see if a Class object is a subclass of the given class.
35
- #
36
- # @param [Class] klass Class we are checking if this is a subclass of.
37
- #
38
- # @return [Boolean] If self is a subclass of klass
39
- def subclass_of?(klass)
40
- check_type(klass, Class, 'klass')
41
-
42
- if (superklass = self.superclass)
43
- superklass == klass or superklass.subclass_of?(klass)
44
- else
45
- false
36
+ # Checks to see if a Class object is a subclass of the given class.
37
+ #
38
+ # @param [Class] klass Class we are checking if this is a subclass of.
39
+ #
40
+ # @return [Boolean] If self is a subclass of klass
41
+ def subclass_of?(klass)
42
+ check_type(klass, Class, blame: 'klass')
43
+
44
+ if (superklass = self.superclass)
45
+ superklass == klass or superklass.subclass_of?(klass)
46
+ else
47
+ false
48
+ end
46
49
  end
47
50
  end
48
51
  end
@@ -1,7 +1,7 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
2
- # Project: Filigree
3
- # Date: 2013/05/15
4
- # Description: A module to automatically extend classes with an inner module.
1
+ # Author: Chris Wailes <chris.wailes+filigree@gmail.com>
2
+ # Project: Filigree
3
+ # Date: 2013/05/15
4
+ # Description: A module to automatically extend classes with an inner module.
5
5
 
6
6
  ############
7
7
  # Requires #
@@ -1,7 +1,7 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
2
- # Project: Filigree
3
- # Date: 2013/05/14
4
- # Description: Easy application configuration.
1
+ # Author: Chris Wailes <chris.wailes+filigree@gmail.com>
2
+ # Project: Filigree
3
+ # Date: 2013/05/14
4
+ # Description: Easy application configuration.
5
5
 
6
6
  ############
7
7
  # Requires #
@@ -12,12 +12,13 @@
12
12
  # Filigree
13
13
  require 'filigree/class_methods_module'
14
14
  require 'filigree/configuration'
15
+ require 'filigree/string'
15
16
 
16
17
  ##########
17
18
  # Errors #
18
19
  ##########
19
20
 
20
- class CommandNotFoundError < RuntimeError
21
+ class CommandNotFoundError < RuntimeError
21
22
  def initialize(line)
22
23
  super "No command found for '#{line}'"
23
24
  end
@@ -117,7 +118,7 @@ module Filigree
117
118
  # @return [void]
118
119
  def config(&block)
119
120
  @config = Class.new { include Filigree::Configuration }
120
- @config.instance_exec &block
121
+ @config.instance_exec(&block)
121
122
  end
122
123
 
123
124
  # Attaches the provided help string to the command that is
@@ -217,6 +218,7 @@ module Filigree
217
218
  # The default help command. This can be added to your class via
218
219
  # add_command.
219
220
  HELP_COMMAND = Command.new('help', 'Prints this help message.', [], nil, Proc.new do
221
+
220
222
  puts 'Usage: <command> [options] <args>'
221
223
  puts
222
224
  puts 'Commands:'
@@ -1,4 +1,4 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
1
+ # Author: Chris Wailes <chris.wailes+filigree@gmail.com>
2
2
  # Project: Filigree
3
3
  # Date: 2013/05/14
4
4
  # Description: Easy application configuration.
@@ -137,7 +137,7 @@ module Filigree
137
137
  break if str == '--'
138
138
 
139
139
  if option = find_option(str)
140
- args = argv.shift(option.arity == -1 ? argv.index { |str| str[0,1] == '-' } : option.arity)
140
+ args = argv.shift(option.arity == -1 ? argv.index { |sub_str| sub_str[0,1] == '-' } : option.arity)
141
141
 
142
142
  case option.handler
143
143
  when Array
@@ -165,7 +165,7 @@ module Filigree
165
165
  def handle_serialized_options(overloaded, set_opts)
166
166
  options =
167
167
  if overloaded.is_a? String
168
- if File.exists? overloaded
168
+ if File.exist? overloaded
169
169
  YAML.load_file overloaded
170
170
  else
171
171
  YAML.load overloaded
@@ -267,8 +267,6 @@ module Filigree
267
267
  # @return [void]
268
268
  def option(long, short = nil, conversions: nil, &block)
269
269
 
270
- attr_accessor long.to_sym
271
-
272
270
  long = long.to_s
273
271
  short = short.to_s if short
274
272
 
@@ -352,7 +350,7 @@ module Filigree
352
350
  # Print the option information out as a string.
353
351
  #
354
352
  # Layout:
355
- # | ||--`long`,|| ||-`short`|| - |
353
+ # | ||--`long`,|| ||-`short`|| ~ |
356
354
  # |_______||_________||_||________||___|
357
355
  # indent max_l+3 1 max_s+1 3
358
356
  #
@@ -366,9 +364,9 @@ module Filigree
366
364
  segmented_help = self.help.segment(segment_indent)
367
365
 
368
366
  if self.short
369
- sprintf "#{' ' * indent}%-#{max_long + 3}s %-#{max_short + 1}s - %s", "--#{self.long},", '-' + self.short, segmented_help
367
+ sprintf "#{' ' * indent}%-#{max_long + 3}s %-#{max_short + 1}s ~ %s", "--#{self.long},", '-' + self.short, segmented_help
370
368
  else
371
- sprintf "#{' ' * indent}%-#{max_long + max_short + 5}s - %s", '--' + self.long, segmented_help
369
+ sprintf "#{' ' * indent}%-#{max_long + max_short + 5}s ~ %s", '--' + self.long, segmented_help
372
370
  end
373
371
  end
374
372
 
@@ -1,4 +1,4 @@
1
- # Author: Chris Wailes <chris.wailes@gmail.com>
1
+ # Author: Chris Wailes <chris.wailes+filigree@gmail.com>
2
2
  # Project: Filigree
3
3
  # Date: 2013/05/04
4
4
  # Description: Pattern matching for Ruby.
@@ -22,152 +22,158 @@ require 'filigree/class'
22
22
  # An error that indicates that no pattern matched a given object.
23
23
  class MatchError < RuntimeError; end
24
24
 
25
+ ###########
26
+ # Methods #
27
+ ###########
28
+
29
+ # This is an implementation of pattern matching. The objects passed to match
30
+ # are tested against the patterns defined inside the match block. The return
31
+ # value of `match` will be the result of evaluating the block given to `with`.
32
+
33
+ # The most basic pattern is the literal. Here, the object or objects being
34
+ # matched will be tested for equality with value passed to `with`. In the
35
+ # example below, the call to `match` will return `:one`. Similar to the
36
+ # literal pattern is the wildcard pattern `_`. This will match any object.
37
+
38
+ # You may also match against variables. This can sometimes conflict with the
39
+ # next kind of pattern, which is a binding pattern. Here, the pattern will
40
+ # match any object, and then make the object it matched available to the with
41
+ # block via an attribute reader. This is accomplished using the method_missing
42
+ # callback, so if there is a variable or function with that name you might
43
+ # accidentally compare against a variable. To bind to a name that is already
44
+ # in scope you can use the {Filigree::MatchEnvironment#Bind} method. In
45
+ # addition, class and destructuring pattern results (see bellow) can be bound
46
+ # to a variable by using the {Filigree::BasicPattern#as} method.
47
+
48
+ # If you wish to match string patterns you may use regular expressions. Any
49
+ # object that isn't a string will fail to match against a regular expression.
50
+ # If the object being matched is a string then the regular expressions `match?`
51
+ # method is used. The result of the regular expression match is available
52
+ # inside the with block via the match_data accessor.
53
+
54
+ # When a class is used in a pattern it will match any object that is an
55
+ # instance of that class. If you wish to compare one regular expression to
56
+ # another, or one class to another, you can force the comparison using the
57
+ # {Filigree::MatchEnvironment#Literal} method.
58
+ #
59
+ # Destructuring patterns allow you to match against an instance of a class,
60
+ # while simultaneously binding values stored inside the object to variables
61
+ # in the context of the with block. A class that is destructurable must
62
+ # include the {Filigree::Destructurable} module. You can then destructure an
63
+ # object as shown bellow.
64
+
65
+ # Both `match` and `with` can take multiple arguments. When this happens, each
66
+ # object is paired up with the corresponding pattern. If they all match, then
67
+ # the `with` clause matches. In this way you can match against tuples.
68
+
69
+ # Any with clause can be given a guard clause by passing a lambda as the last
70
+ # argument to `with`. These are evaluated after the pattern is matched, and
71
+ # any bindings made in the pattern are available to the guard clause.
72
+
73
+ # If you wish to evaluate the same body on matching any of several patterns you
74
+ # may list them in order and then specify the body for the last pattern in the
75
+ # group.
76
+
77
+ # Patterns are evaluated in the order in which they are defined and the first
78
+ # pattern to match is the one chosen. You may define helper methods inside the
79
+ # match block. They will be re-defined every time the match statement is
80
+ # evaluated, so you should move any definitions outside any match calls that
81
+ # are being evaluated often.
82
+
83
+ # @example The literal pattern
84
+ # def foo(n)
85
+ # match 1 do
86
+ # with(1) { :one }
87
+ # with(2) { :two }
88
+ # with(_) { :other }
89
+ # end
90
+ # end
91
+ #
92
+ # foo(1)
93
+
94
+ # @example Matching against variables
95
+ # var = 42
96
+ # match 42 do
97
+ # with(var) { :hoopy }
98
+ # with(0) { :zero }
99
+ # end
100
+
101
+ # @example Binding patterns
102
+ # # Returns 42
103
+ # match 42 do
104
+ # with(x) { x }
105
+ # end
106
+
107
+ # x = 3
108
+ # # Returns 42
109
+ # match 42 do
110
+ # with(Bind(:x)) { x }
111
+ # with(42) { :hoopy }
112
+ # end
113
+
114
+ # @example Regular expression and class instance pattern
115
+ # def matcher(object)
116
+ # match object do
117
+ # with(/hoopy/) { 42 }
118
+ # with(Integer) { 'hoopy' }
119
+ # end
120
+ # end
121
+
122
+ # # Returns 42
123
+ # matcher('hoopy')
124
+ # # Returns 'hoopy'
125
+ # matcher(42)
126
+
127
+ # @example Destructuring an object
128
+ # class Foo
129
+ # include Filigree::Destructurable
130
+ # def initialize(a, b)
131
+ # @a = a
132
+ # @b = b
133
+ # end
134
+ #
135
+ # def destructure(_)
136
+ # [@a, @b]
137
+ # end
138
+ # end
139
+
140
+ # # Returns true
141
+ # match Foo.new(4, 2) do
142
+ # with(Foo.(4, 2)) { true }
143
+ # with(_) { false }
144
+ # end
145
+
146
+ # @example Using guard clauses
147
+ # match o do
148
+ # with(n, -> { n < 0 }) { :NEG }
149
+ # with(0) { :ZERO }
150
+ # with(n, -> { n > 0 }) { :POS }
151
+ # end
152
+ #
153
+ # @param [Object] objects Objects to be matched
154
+ # @param [Proc] block Block containing with clauses.
155
+ #
156
+ # @return [Object] Result of evaluating the matched pattern's block
157
+ def match(*objects, &block)
158
+ me = Filigree::MatchEnvironment.new
159
+
160
+ me.instance_exec(&block)
161
+
162
+ me.find_match(objects)
163
+ end
164
+
25
165
  #######################
26
166
  # Classes and Modules #
27
167
  #######################
28
168
 
29
169
  module Filigree
30
170
 
171
+ using Filigree
172
+
31
173
  ###########
32
174
  # Methods #
33
175
  ###########
34
176
 
35
- # This is an implementation of pattern matching. The objects passed to match
36
- # are tested against the patterns defined inside the match block. The return
37
- # value of `match` will be the result of evaluating the block given to `with`.
38
-
39
- # The most basic pattern is the literal. Here, the object or objects being
40
- # matched will be tested for equality with value passed to `with`. In the
41
- # example below, the call to `match` will return `:one`. Similar to the
42
- # literal pattern is the wildcard pattern `_`. This will match any object.
43
-
44
- # You may also match against variables. This can sometimes conflict with the
45
- # next kind of pattern, which is a binding pattern. Here, the pattern will
46
- # match any object, and then make the object it matched available to the with
47
- # block via an attribute reader. This is accomplished using the method_missing
48
- # callback, so if there is a variable or function with that name you might
49
- # accidentally compare against a variable. To bind to a name that is already
50
- # in scope you can use the {Filigree::MatchEnvironment#Bind} method. In
51
- # addition, class and destructuring pattern results (see bellow) can be bound
52
- # to a variable by using the {Filigree::BasicPattern#as} method.
53
-
54
- # If you wish to match string patterns you may use regular expressions. Any
55
- # object that isn't a string will fail to match against a regular expression.
56
- # If the object being matched is a string then the regular expressions `match?`
57
- # method is used. The result of the regular expression match is available
58
- # inside the with block via the match_data accessor.
59
-
60
- # When a class is used in a pattern it will match any object that is an
61
- # instance of that class. If you wish to compare one regular expression to
62
- # another, or one class to another, you can force the comparison using the
63
- # {Filigree::MatchEnvironment#Literal} method.
64
- #
65
- # Destructuring patterns allow you to match against an instance of a class,
66
- # while simultaneously binding values stored inside the object to variables
67
- # in the context of the with block. A class that is destructurable must
68
- # include the {Filigree::Destructurable} module. You can then destructure an
69
- # object as shown bellow.
70
-
71
- # Both `match` and `with` can take multiple arguments. When this happens, each
72
- # object is paired up with the corresponding pattern. If they all match, then
73
- # the `with` clause matches. In this way you can match against tuples.
74
-
75
- # Any with clause can be given a guard clause by passing a lambda as the last
76
- # argument to `with`. These are evaluated after the pattern is matched, and
77
- # any bindings made in the pattern are available to the guard clause.
78
-
79
- # If you wish to evaluate the same body on matching any of several patterns you
80
- # may list them in order and then specify the body for the last pattern in the
81
- # group.
82
-
83
- # Patterns are evaluated in the order in which they are defined and the first
84
- # pattern to match is the one chosen. You may define helper methods inside the
85
- # match block. They will be re-defined every time the match statement is
86
- # evaluated, so you should move any definitions outside any match calls that
87
- # are being evaluated often.
88
-
89
- # @example The literal pattern
90
- # def foo(n)
91
- # match 1 do
92
- # with(1) { :one }
93
- # with(2) { :two }
94
- # with(_) { :other }
95
- # end
96
- # end
97
- #
98
- # foo(1)
99
-
100
- # @example Matching against variables
101
- # var = 42
102
- # match 42 do
103
- # with(var) { :hoopy }
104
- # with(0) { :zero }
105
- # end
106
-
107
- # @example Binding patterns
108
- # # Returns 42
109
- # match 42 do
110
- # with(x) { x }
111
- # end
112
-
113
- # x = 3
114
- # # Returns 42
115
- # match 42 do
116
- # with(Bind(:x)) { x }
117
- # with(42) { :hoopy }
118
- # end
119
-
120
- # @example Regular expression and class instance pattern
121
- # def matcher(object)
122
- # match object do
123
- # with(/hoopy/) { 42 }
124
- # with(Integer) { 'hoopy' }
125
- # end
126
- # end
127
-
128
- # # Returns 42
129
- # matcher('hoopy')
130
- # # Returns 'hoopy'
131
- # matcher(42)
132
-
133
- # @example Destructuring an object
134
- # class Foo
135
- # include Filigree::Destructurable
136
- # def initialize(a, b)
137
- # @a = a
138
- # @b = b
139
- # end
140
- #
141
- # def destructure(_)
142
- # [@a, @b]
143
- # end
144
- # end
145
-
146
- # # Returns true
147
- # match Foo.new(4, 2) do
148
- # with(Foo.(4, 2)) { true }
149
- # with(_) { false }
150
- # end
151
-
152
- # @example Using guard clauses
153
- # match o do
154
- # with(n, -> { n < 0 }) { :NEG }
155
- # with(0) { :ZERO }
156
- # with(n, -> { n > 0 }) { :POS }
157
- # end
158
- #
159
- # @param [Object] objects Objects to be matched
160
- # @param [Proc] block Block containing with clauses.
161
- #
162
- # @return [Object] Result of evaluating the matched pattern's block
163
- def match(*objects, &block)
164
- me = Filigree::MatchEnvironment.new
165
-
166
- me.instance_exec &block
167
-
168
- me.find_match(objects)
169
- end
170
-
171
177
  # Wrap non-pattern objects in pattern objects so they can all be treated
172
178
  # in the same way during pattern sorting and matching.
173
179
  #
@@ -263,7 +269,7 @@ module Filigree
263
269
  @patterns << (mp = OuterPattern.new(pattern, guard, block))
264
270
 
265
271
  if block
266
- @deferred.each { |pattern| pattern.block = block }
272
+ @deferred.each { |deferred_pattern| deferred_pattern.block = block }
267
273
  @deferred.clear
268
274
 
269
275
  else
@@ -613,10 +619,11 @@ module Filigree
613
619
  end
614
620
  end
615
621
 
616
- ###################################
617
- # Standard Library Deconstructors #
618
- ###################################
622
+ ################################
623
+ # Standard Library Refinements #
624
+ ################################
619
625
 
626
+ # TODO: Figure out how to put this into a refinement.
620
627
  class Array
621
628
  extend Filigree::Destructurable
622
629
 
@@ -627,7 +634,7 @@ class Array
627
634
  # second elements, and then an array containing the remainder of the
628
635
  # values.
629
636
  #
630
- # @param [Fixnum] num_elems Number of sub-pattern elements
637
+ # @param [Integer] num_elems Number of sub-pattern elements
631
638
  #
632
639
  # @return [Array<Object>]
633
640
  def destructure(num_elems)
@@ -635,30 +642,34 @@ class Array
635
642
  end
636
643
  end
637
644
 
638
- class Class
639
- # Causes an instance of a class to be bound the the given name.
640
- #
641
- # @param [BindingPattern] binding_pattern Name to bind the instance to
642
- def as(binding_pattern)
643
- binding_pattern.tap { |bp| bp.pattern_elem = Filigree::InstancePattern.new(self) }
645
+ module Filigree
646
+
647
+ refine Class do
648
+ # Causes an instance of a class to be bound the the given name.
649
+ #
650
+ # @param [BindingPattern] binding_pattern Name to bind the instance to
651
+ def as(binding_pattern)
652
+ binding_pattern.tap { |bp| bp.pattern_elem = Filigree::InstancePattern.new(self) }
653
+ end
644
654
  end
645
- end
646
655
 
647
- class Regexp
648
- # Causes a string matching the regular expression to be bound the the
649
- # given name.
650
- #
651
- # @param [BindingPattern] binding_pattern Name to bind the instance to
652
- def as(binding_pattern)
653
- binding_pattern.tap { |bp| bp.pattern_elem = Filigree::RegexpPattern.new(self) }
656
+ refine Regexp do
657
+ # Causes a string matching the regular expression to be bound the the
658
+ # given name.
659
+ #
660
+ # @param [BindingPattern] binding_pattern Name to bind the instance to
661
+ def as(binding_pattern)
662
+ binding_pattern.tap { |bp| bp.pattern_elem = Filigree::RegexpPattern.new(self) }
663
+ end
654
664
  end
655
- end
656
665
 
657
- class Symbol
658
- # Turns a symbol into a binding pattern.
659
- #
660
- # @return [Filigree::BindingPattern]
661
- def ~
662
- Filigree::BindingPattern.new(self)
666
+ refine Symbol do
667
+ # Turns a symbol into a binding pattern.
668
+ #
669
+ # @return [Filigree::BindingPattern]
670
+ def ~
671
+ Filigree::BindingPattern.new(self)
672
+ end
663
673
  end
674
+
664
675
  end