J
John Conti
Hi all,
I am not sure if my question is relatively obvious or instead arcane.
Being new to ruby, I am trying out some of the metaprogramming features
to generate sets of orthogonal methods for decoding various string
types. I want to provide these methods as mix-ins so many of my classes
can decode these specialized strings. The methods have lots of
repetitive code and are easily reduced using lambdas (think DRY).
However, all has not gone as I expected. This works:
module Fix
def self.manage()
lambda do
what = foo? ? "fix" : "leave"
"Let's " + what + " it"
end
end
module_eval %{define_method :maintenance, manage}
end
class X
include Fix
def foo?; true; end
end
class Y
include Fix
def foo?; false; end
end
puts X.new.maintenance
puts Y.new.maintenance
# Let's fix it
# Let's leave it
This does not:
module Fix
def self.doer()
lambda do
foo? ? "fix" : "leave"
end
end
def self.manage()
grunt = doer
lambda do
"Let's " + grunt.call + " it"
end
end
module_eval %{define_method :maintenance, manage}
end
class X
include Fix
def foo?; true; end
end
class Y
include Fix
def foo?; false; end
end
puts X.new.maintenance
puts Y.new.maintenance
# lambda2.rb:4:in `doer': undefined method `foo?' for Fix:Module
(NoMethodError)
# from lambda2.rb:10:in `call'
# from lambda2.rb:10:in `maintenance'
# from lambda2.rb:25
In the first example, the call to the method the mixin module relies on
gets called without problem. I. e. the instance method of the mixin
finds the object's instance method. However, in the second example,
methods are not looked up the same way, the module is searched and so it
fails.
What about the second example's closure on the lambda is causing
method's to be looked up differently? I do not feel like I have a good
mental model of the method lookup and scoping rules of Ruby. The latest
book I've looked at (Programming Ruby) doesn't seem to shed much light
on my issue.
Can anyone give me an explanation to help?
Thank you,
John
I am not sure if my question is relatively obvious or instead arcane.
Being new to ruby, I am trying out some of the metaprogramming features
to generate sets of orthogonal methods for decoding various string
types. I want to provide these methods as mix-ins so many of my classes
can decode these specialized strings. The methods have lots of
repetitive code and are easily reduced using lambdas (think DRY).
However, all has not gone as I expected. This works:
module Fix
def self.manage()
lambda do
what = foo? ? "fix" : "leave"
"Let's " + what + " it"
end
end
module_eval %{define_method :maintenance, manage}
end
class X
include Fix
def foo?; true; end
end
class Y
include Fix
def foo?; false; end
end
puts X.new.maintenance
puts Y.new.maintenance
# Let's fix it
# Let's leave it
This does not:
module Fix
def self.doer()
lambda do
foo? ? "fix" : "leave"
end
end
def self.manage()
grunt = doer
lambda do
"Let's " + grunt.call + " it"
end
end
module_eval %{define_method :maintenance, manage}
end
class X
include Fix
def foo?; true; end
end
class Y
include Fix
def foo?; false; end
end
puts X.new.maintenance
puts Y.new.maintenance
# lambda2.rb:4:in `doer': undefined method `foo?' for Fix:Module
(NoMethodError)
# from lambda2.rb:10:in `call'
# from lambda2.rb:10:in `maintenance'
# from lambda2.rb:25
In the first example, the call to the method the mixin module relies on
gets called without problem. I. e. the instance method of the mixin
finds the object's instance method. However, in the second example,
methods are not looked up the same way, the module is searched and so it
fails.
What about the second example's closure on the lambda is causing
method's to be looked up differently? I do not feel like I have a good
mental model of the method lookup and scoping rules of Ruby. The latest
book I've looked at (Programming Ruby) doesn't seem to shed much light
on my issue.
Can anyone give me an explanation to help?
Thank you,
John