lib/patternmatching/pattern.rb in patternmatching-0.1.4 vs lib/patternmatching/pattern.rb in patternmatching-0.2.0
- old
+ new
@@ -115,37 +115,50 @@
begin
Collector.walk(source, target, args)
rescue NotMatched
next
end
- return ExecuteAs.new(args, receiver).call(&action)
+ return ExecuteAs.new(args, receiver).instance_eval(&action)
end
end
+ # Private class to access instance valiables of the receiver
+ class InstanceVariableAccessor
+ def initialize(receiver)
+ @receiver = receiver
+ end
+ def method_missing(name, *args)
+ begin
+ @receiver.send(name, *args)
+ rescue NameError
+ if name.to_s[-1,1] == "="
+ field = "@" + name.to_s[0...-1]
+ @receiver.instance_variable_set(field, args[0])
+ else
+ field = "@" + name.to_s
+ @receiver.instance_variable_get(field, args[0])
+ end
+ end
+ end
+ end
+
#Private class enabling to use the name of symbols in patterns
#like a local variables in action blocks
class ExecuteAs
def initialize(args, receiver)
- @this = receiver
+ @receiver = receiver
+ @wrapper = InstanceVariableAccessor.new receiver
@args = args
end
- def call(&action)
- args = @args
- mod = Module.new
- mod.instance_eval do
- define_method(:method_missing) do |name, *margs|
- return args[name] if args.key?(name)
- super(name, *margs)
- end
- end
- # this block is not thread safe
- @this.extend mod
- result = @this.instance_eval(&action)
- mod.instance_eval do
- remove_method(:method_missing)
- end
- #
- result
+ def this
+ @receiver
+ end
+ def the
+ @wrapper
+ end
+ def method_missing(name, *args)
+ return @args[name] if @args.key?(name)
+ @receiver.send(name, *args)
end
end
end
#Private class for collecting pattern/action fragments