在 Ruby 中,如何获取对包含用于调用的参数的方法的引用?

发布于 2024-08-11 05:27:32 字数 452 浏览 4 评论 0原文

给出这段代码:

a = {1=>2}
m = a.method(:[])

我知道我现在可以使用 :

value = m.call(1)

,它将返回 2。问题是,我需要更改什么,以便我可以像 : 一样直接调用该方法,

m.call()

并且它将得到 1 作为参数发送?如果能够编写如下内容那就太好了:

m = a.method(:[],1) # where the symbol is the method, and 1 will be the parameter it will be called with

问题是,我想延迟执行脚本的某些部分,直到创建一些对象,并且我想避免重写所有内容以使用 lambda。

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 parameter? 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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

み零 2024-08-18 05:27:32

基本上,您想要的是一种柯里化函数的方法。

http://en.wikipedia.org/wiki/Curry_function

这可以通过许多不同的方式完成方式之一:

def curry(method, *params)
  lambda { send method, *params }
end

您可以将其添加到 Hash 的元类中,或者添加到您想要包含在某些对象中的模块中,等等。然后,调用它就成为您想要的用例:

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

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
淡莣 2024-08-18 05:27:32

我确信,有不止一种方法可以做到这一点。

a = {1=>2}

class << a
  def fetch_what(key)
    Proc.new { self[key] }
  end
end

....

m = a.fetch_what(1)
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
森罗 2024-08-18 05:27:32

听起来您应该将方法参数附加到您正在调用该方法的对象,并让该方法将它们作为实例变量访问。

就简单的重构步骤而言:

  • 引入新的实例变量,每个方法参数一个。
  • 为实例变量引入新的访问器。
  • 如果未提供参数,请重构该方法以使用实例变量。
  • 在方法调用之前的某个时刻重构调用代码以通过访问器设置实例变量。
  • 重构调用代码以在方法调用中不传递任何参数。

例如,重构调用代码如下:

widget = Widget.new
assembly_method = widget.method(:assemble)
# Time passes...
assembly_method.call(:electric, :smooth)

像这样工作:

widget = Widget.new
widget.frombulator = :electric
widget.jazzifier = :smooth
assembly_method = widget.method(:assemble)
# Time passes...
assembly_method.call

它并不性感或聪明,但它会产生表达其意图的代码,并且很有可能它会解决真正的问题,即您的代码中缺少某些东西。模型。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文