更清晰的方法来定义没有lambda的方法

时间:2012-05-30 08:50:14

标签: ruby-on-rails ruby closures metaprogramming

在Ruby中创建闭包是否有更容易和/或更具可读性方式,以便定义的方法访问变量 m

我在这里遇到了lambda的轻微“问题”。

我经常动态定义必须访问局部变量的方法:

例如:

class Comparison

  def income
    123
  end

  def sales
    42342
  end

  # and a dozen of other methods

  # Generate xxx_after_tax for each method
  instance_methods(false).each do |m|
    lambda {
      define_method("#{m}_after_tax") do
        send(m) * 0.9
      end
    }.call
  end
end

5 个答案:

答案 0 :(得分:5)

class Comparison

  def income
    123
  end

  def sales
    42342
  end

  # and a dozen of other methods

  # Generate xxx_after_tax for each method
  instance_methods(false).each do |m|

    define_method("#{m}_after_tax") do
      send(m) * 0.9
    end

  end
end

答案 1 :(得分:3)

常规方法定义不是闭包,但是在这里您使用块调用define_method,并且块闭包。这应该足够了:

instance_methods(false).each do |m|
  define_method :"#{m}_after_tax" do
    send(m) * 0.9
  end
end

答案 2 :(得分:2)

正如Yuri指出的那样,lambda是多余的,您可以通过运行此示例看到。

#!/usr/bin/env ruby -w

class Foo
  [:foo, :bar].each do |m|
    define_method("#{m}_dynamic") do
      "Called #{m}"
    end
  end
end

p Foo.new.foo_dynamic # => "Called foo"

答案 3 :(得分:1)

  instance_methods(false).each do |m|
    class_eval <<-ERUBY, __FILE__, __LINE__
      def #{m}_after_tax
        #{m} * 0.9
      end
    ERUBY
  end

答案 4 :(得分:0)

您可以像这样使用method_missing:

def method_missing(name, *args, &block)
  if name.to_s.match /^([a-z_]+)_after_tax$/
    send($1)
  else
    super
  end
end

我希望这会有所帮助。