Ruby相当于类似Lisp的“应用”吗?

时间:2019-01-24 16:49:58

标签: ruby functional-programming

我想创建一个实例方法,该方法将其自身类的另一个实例方法作为参数,然后将传递的方法应用于它正在处理的实例(称为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 :(得分:3)

使用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!

答案 1 :(得分:1)

这用 functional-programming 进行了标记,所以我将提供一个持久的(不变的)设计-

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]