Как я могу получить ссылку на метод, который содержит аргументы, используемые для вызовов, в Ruby? - PullRequest
2 голосов
/ 10 ноября 2009

Учитывая этот код:

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

Дело в том, что я хотел бы отложить выполнение определенных частей моего скрипта до тех пор, пока не будут созданы некоторые объекты, и я бы хотел избежать переписывания ВСЕГО для использования лямбд.

Ответы [ 3 ]

3 голосов
/ 10 ноября 2009

По сути, вам нужен способ карри функции.

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
3 голосов
/ 10 ноября 2009

Существует несколько способов сделать это, я уверен.

a = {1=>2}

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

....

m = a.fetch_what(1)
m.call()  # -> 2
0 голосов
/ 10 ноября 2009

Звучит так, как будто вы должны присоединить параметры метода к объекту, для которого вызываете метод, и иметь метод, который обращается к ним как к переменным экземпляра.

С точки зрения простых шагов рефакторинга:

  • Ввести новые переменные экземпляра, по одной на параметр метода.
  • Ввести новые методы доступа для переменных экземпляра.
  • Измените метод для использования переменных экземпляра, если параметры не указаны.
  • Рефакторинг вызывающего кода для установки переменных экземпляра через методы доступа в некоторый момент до вызова метода.
  • Измените код вызова, чтобы не передавать параметры в вызове метода.

Например, рефакторинг вызывающего кода: </p> <pre> widget = Widget.new assembly_method = widget.method(:assemble) # Time passes... assembly_method.call(:electric, :smooth) </pre> <p>

работать так: </p> <pre> widget = Widget.new widget.frombulator = :electric widget.jazzifier = :smooth assembly_method = widget.method(:assemble) # Time passes... assembly_method.call </pre> <p>

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...