Рубиновый эквивалент lisp-подобного "apply"? - PullRequest
0 голосов
/ 24 января 2019

Я хотел бы создать метод экземпляра, который принимает в качестве параметра другой метод экземпляра своего собственного класса, а затем применяет переданный метод к экземпляру, с которым он работает (известный как self):

class MyClass

  attr_reader :called_methods

  def initialize
    @called_methods = []
  end

  def my_first_method!
    @called_methods << :my_first_method
    self
  end

  def my_second_method!
    @called_methods << :my_second_method
    self
  end

  def my_strange_method!(secondary)
    # Want to apply method whose name is given by secondary, to self
  end
end

p MyClass.new.my_second_method!.my_strange_method!(:my_first_method!).called_methods

Я подозреваю, что унарный & может быть ключевым, но все веб-страницы, которые я могу найти в этом операторе, включают вызов методов для нескольких объектов, как при итерации по Enumerable с #each или #map.

Ответы [ 2 ]

0 голосов
/ 24 января 2019

Это помечено функциональным программированием , поэтому я собираюсь предложить постоянный (неизменный) дизайн -

class MyClass

  attr_reader :called_methods

  def initialize(m = [])
    @called_methods = m
  end

  def my_first_method!
    MyClass.new(called_methods + [ :first ])
  end

  def my_second_method!
    MyClass.new(called_methods + [ :second ])
  end

  def my_strange_method!(secondary)
    public_send secondary
  end
end

MyClass.new.my_second_method!.my_strange_method!(:my_first_method!).called_methods
# [:second, :first]
0 голосов
/ 24 января 2019

Используйте Object#public_send (или Object#send, чтобы применить защищенный / частный метод).

def my_strange_method!(secondary)
  public_send(secondary)
  self
end

p MyClass.new.
    my_second_method!.
    my_strange_method!(:my_first_method!).
    called_methods
#⇒ [:my_second_method, :my_first_method]

Может быть более оборонительный путьприменять, если известен только метод:

def my_strange_method!(secondary)
  raise ArgumentError.new("Unknown method #{secondary}") \
    unless methods.include? secondary.to_s.to_sym
  public_send(secondary)
end

p MyClass.new.
    my_second_method!.
    my_strange_method!(:my_first_method!).
    called_methods
#⇒ [:my_second_method, :my_first_method]

p MyClass.new.
    my_second_method!.
    my_strange_method!(:inexisting_method!).
    called_methods
#⇒ ArgumentError: Unknown method inexisting_method!
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...