有没有一种方法可以在没有 运行 该函数的情况下将实例方法存储在变量中?在 Ruby

Is there a way to store an instance method inside a variable without running that function first? In Ruby

我正在尝试将一个实例方法存储为一个变量,这样我就可以将它传递到一种方法中,以便在我正在构建的菜单上存储逻辑。

例如,我希望我的 our_startup.prompt 方法存储在我的 start_game_ui.logic 数组中。我正在尝试使用 start_game_ui.set_logic 函数来执行此操作,该函数将参数铲入逻辑数组。我想将 6 种方法铲到逻辑数组中,这样当我 运行 我的最终函数放置和接收输入 1 - 6 时。如果用户选择 1 它应该 运行 函数在数组的第一个元素中。

our_startup = Startup.new("No Name")

## START GAME UI ##
start_game_ui = UI.new("start_game_ui")
start_game_ui.menu_items = ["[1] - Yes", "[2] - Generate Another"]

##set up logic##
method1_test = our_startup.set_name("test")
rerun = start_game_ui.prompt
start_game_ui.set_logic(method1_test, rerun)

当我 运行 这个时,我的 start_game_ui.prompt 方法将 运行。我想将 start_game_ui.prompt 方法存储在该变量 rerun 中,而没有方法 运行.

一旦我 运行 我的最终方法并选择 1 它应该 return "test"。然而,当我 运行 这个它 运行s start_game_ui.prompt 而我不想要它。

希望你能明白我的意思。如果你还不知道的话,我有 2 类 UIStartup

请不要告诉我我能做到method(:something) 这没有帮助,因为它是一个被另一个实例调用的实例方法。除非你能告诉我如何让那个符号与实例中的正确方法相对应。我已经试过了 method(our_startup.prompt) 但它不起作用。

如果您想从对象实例中获取实例方法,那么您可以使用:our_startup.method(:prompt)

我不太明白你的最终目标是什么,所以我建议你进一步阅读 Ruby 的对象模型和方法,并为你提供一些指导。

method 方法 returns Method 的一个实例(一个对象)。如果这令人困惑,请慢慢阅读并查看 the Method documentation。参数引用的方法是否是实例方法与 method 方法的行为无关。

直接解决您在问题中所说的内容:使用 method(:foo) 不会调用引用的方法(例如 foo)。

可以 从源接收器解除绑定方法(创建无法调用的 UnboundMethod )并在需要时将其重新绑定到另一个接收器:

my_method_instance = some_string.method(:to_s)

# Now I can call `some_string.to_s` like so:
my_method_instance.to_s

# This isn't very useful for `to_s`, but it could be in other situations
method_instance = SomeModule::SomeHelper.method(:parse_html)
array_of_html_docs = array_of_strings.map(&method_instance)

# And you can unbind the method from the original receiver:
my_unbound_method_instance = my_method_instance.unbind

# And rebind it elsewhere
my_unbound_method_instance.bind(some_other_receiver)
my_unbound_method_instance.call(args) # receiver is `some_other_receiver` here

PLEASE DO NOT TELL ME I CAN DO method(:something) this does not help as it is an instance method being called by another instance.

我真的不想告诉你,但不幸的是,正确答案:

rerun = start_game_ui.method(:prompt)
# Then, later when you need to call it:
result = rerun.()

Not 使用 Object#method,正如您在问题中所要求的那样,会显着增加复杂性,例如通过分别传递接收者和方法的名称:

rerun_receiver_and_message = [start_game_ui, :prompt]
# Then, later when you need to call it:
result = rerun_receiver_and_message.first.public_send(rerun_receiver_and_message.last)

唯一可以存储在变量中并作为参数传递的是对象。

Procs 和 Lambdas 是对象,所以你应该可以做类似的事情

rerun = -> {start_game_ui.prompt}
start_game_ui.set_logic(method1_test, rerun)

rerun 正在存储对方法的调用,而不是方法的结果

在你需要执行方法的时候,你会做

rerun.call

请注意,Procs 和 Lambdas 也可以指定参数,您可以在调用时提供这些参数。

我不确定这是否对您的问题有帮助,但希望能。