Есть ли способ сохранить метод экземпляра внутри переменной без предварительного запуска этой функции? В Ruby - PullRequest
0 голосов
/ 12 января 2020

Я пытаюсь сохранить метод экземпляра как переменную, чтобы я мог передать его в способ хранения логики c в строящемся меню.

Например, я хочу свой our_startup.prompt метод для хранения в моем массиве start_game_ui.logic. Я пытаюсь сделать это с помощью функции start_game_ui.set_logic, которая помещает аргументы в массив logi c. Я хотел бы добавить 6 методов в массив logi c, чтобы при запуске последней функции помещать и получать ввод 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, он должен вернуть "test". Однако, когда я запускаю это, он запускает start_game_ui.prompt, и я не хочу этого.

Я надеюсь, вы понимаете, что я имею в виду. У меня есть 2 класса UI и Startup, если вы не могли сказать.

ПОЖАЛУЙСТА, НЕ СКАЖИ МНЕ Я МОГУ СДЕЛАТЬ method(:something) это не помогает, так как это метод экземпляра, вызываемый другим экземпляром. Если вы не можете сказать мне, как заставить этот символ соответствовать правильному методу внутри экземпляра. Я пробовал method(our_startup.prompt), и он не работает.

Ответы [ 4 ]

3 голосов
/ 12 января 2020

ПОЖАЛУЙСТА, НЕ СКАЖИ МНЕ, Я МОГУ СДЕЛАТЬ method(:something) это не помогает, так как это метод экземпляра, вызываемый другим экземпляром.

Я действительно хотел бы не говорить вам что, к сожалению, является правильным ответом:

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

Не с использованием 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)
1 голос
/ 12 января 2020

Единственное, что вы можете хранить в переменных и передавать в качестве аргументов, это объекты.

Procs и Lambdas являются объектами, поэтому вы должны иметь возможность делать что-то вроде

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

rerun сохраняет вызов метода, а не результаты метода

В тот момент, когда вам нужно выполнить метод, вы должны сделать

rerun.call

Обратите внимание, что Procs и Lambdas могут также укажите аргументы, которые вы можете предоставить во время вызова.

Я не уверен, поможет ли это вашей проблеме, но надеюсь, что это так.

1 голос
/ 12 января 2020

Если вы хотите получить метод экземпляра из экземпляра вашего объекта, вы можете использовать это: our_startup.method(:prompt)

0 голосов
/ 12 января 2020

Я не совсем понимаю, какова ваша конечная цель, поэтому я собираюсь предложить вам немного подробнее прочитать объектную модель и методы Ruby и вместо этого дать вам некоторые рекомендации.

Метод method возвращает экземпляр Method (объект). Если это сбивает с толку, прочитайте его помедленнее и проверьте документацию по методике . Является ли метод, на который ссылается аргумент, методом экземпляра или нет, не имеет отношения к поведению метода 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...