Ruby:将块传递给定义实例方法的类宏

时间:2010-11-09 16:07:47

标签: ruby metaprogramming

我正在努力使用看起来像下面示例的代码(但实际上做了一些有用的事情)。当我想在具有实例方法的实例的上下文中对它进行评估时,传递给def_my_method的块当然是在类的上下文中创建的。我该怎么做?

module Formatters
  # Really useful methods, included in several classes
  def format_with_stars(str)
    return "*** #{str} ***"
  end
end

class Test
  include Formatters
  STRINGS = ["aa", "bb"]

  def self.def_my_method(method_name, another_parameter, &format_proc)
    define_method(method_name) do
      # In reality, some more complex code here, then...
      return STRINGS.map(&format_proc)
    end
  end

  def_my_method(:star_strings, "another_parameter") { |str| format_with_stars(str) }
  # Define other methods
end

tt = Test.new
puts tt.star_strings
# Throws undefined method `format_with_stars' for Test:Class (NoMethodError)

2 个答案:

答案 0 :(得分:3)

您可以使用instance_exec在正确的上下文中执行传递的块。而不是将&format_proc直接传递给map的调用,而是传递一个使用实例exec调用它的块。

这样的事情:

def self.def_my_method(method_name, another_parameter, &format_proc)
  define_method(method_name) do
    # In reality, some more complex code here, then...
    return STRINGS.map{|str| instance_exec(str, &format_proc)}
  end
end

这产生了这个:

$ ruby tt.rb 
*** aa ***
*** bb ***

对我来说(其中tt.rb是我给文件的任意名称),我认为这就是你想要的例子。

答案 1 :(得分:1)


...

class Test
-  include Formatters
+  extend Formatters

...

应该这样做。