Given this code:
a = {1=>2}
m = a.method(:[])
I know that I can now use :
value = m.call(1)
and it will return 2. The thing is, what do I need to change so that I can call the method directly like :
m.call()
and it will get the 1 sent as a paramet开发者_如何学JAVAer? It would be nice to be able to write something like :
m = a.method(:[],1) # where the symbol is the method, and 1 will be the parameter it will be called with
The thing is, I'd like to delay the execution of certain parts of my script until some objects get created, and I'd like to avoid rewriting EVERYTHING to use lambdas.
Basically, what you want is a way to curry the function.
http://en.wikipedia.org/wiki/Curry_function
This can be done in many different ways, one of which:
def curry(method, *params)
lambda { send method, *params }
end
You can add this to Hash's metaclass, or to a module you want to include in some of your objects, etc. Then, calling it becomes the usecase you wanted:
irb(main):001:0> a = {1 => 2}
=> {1=>2}
... # add curry to Hash's metaclass
irb(main):011:0> m = a.curry :[], 1
=> #<Proc:0xb76e2154@(irb):8>
irb(main):012:0> m.call
=> 2
There's more than one way to do it, I'm sure.
a = {1=>2}
class << a
def fetch_what(key)
Proc.new { self[key] }
end
end
....
m = a.fetch_what(1)
m.call() # -> 2
It sounds like you should attach the method parameters to the object you're calling the method on, and have the method access them as instance variables.
In terms of simple refactoring steps:
- Introduce new instance variables, one per method parameter.
- Introduce new accessors for the instance variables.
- Refactor the method to use the instance variables if the parameters are not supplied.
- Refactor the calling code to set the instance variables through the accessors, at some point prior to the method call.
- Refactor the calling code to pass no parameters in the method call.
As an example, refactor calling code like this:
widget = Widget.new assembly_method = widget.method(:assemble) # Time passes... assembly_method.call(:electric, :smooth)
to work like this:
widget = Widget.new widget.frombulator = :electric widget.jazzifier = :smooth assembly_method = widget.method(:assemble) # Time passes... assembly_method.call
It's not sexy or clever, but it will result in code that expresses its intent, and odds are good that it will address the real problem, namely that something is missing from your model.
精彩评论