我正在尝试创建一个泛型方法:
class Foo
attr_reader
def add(object)
item = @item.find { |item| item.(#the method is calling object.class) == object if item.is_a?(object.class)}
end
end我想创建一个泛型方法,它根据参数类比较数组的元素。
示例:
item.method1 == method1 if item.is_a?(method1.class) 其中method1是类的名称。
另外,我需要一个完整的教程关于元编程和动态/泛型编程。
发布于 2011-03-24 10:03:13
我不确定你从你的例子中想要做什么。一般来说,在Ruby中,您不会检查类型。它是动态类型的,原因是:您可以编写适用于任何对象的代码,这些对象恰好支持您的代码对这些对象调用的方法。
从您的评论中可以看出,您希望扩展类Array,以便在调用像an_array.pack这样的数组上的方法时,会在数组中搜索Pack的实例并返回。每当发现一个不存在的方法时,Ruby都会调用一个名为Module#method_missing的方法。例如,如果我随机决定调用4.to_dragon(magic: 4, height: 700),Ruby解释器将尝试将to_dragon作为定义在Fixnum (数字类型)继承链中的某个类或模块上的公共方法来查找。如果您还没有对这个链做过什么奇怪的事情,我们将使用以下参数在对象4上调用method_missing:[:to_dragon, { magic: 4, height: 700 }]。基本上,这是附加在参数前面的名称,应该给出一个块。
使用此技术,您可以覆盖method_missing以获得此代码作为解决方案:
class String
def method_to_class
split('_').map(&:capitalize).join
end
end
class Array
def method_missing(method_name, *arguments, &block)
find do |element|
element.class.name == method_name.to_s.method_to_class
end || super
end
end您可以向String添加一个方法,以将方法名转换为类名。然后,在Array上重新定义method_missing以检查每个元素,查看类名是否与给定的类名匹配。如果找到了一个,那么就返回它。否则(我们使用Ruby奇特的||操作符),从该函数返回的值为nil,并且返回||的第二个操作数。这恰好是method_missing (我们通过super关键字得到的)的默认实现,并返回调用应得的错误。
唯一的潜在问题是,如果您的元素具有与数组中已定义的方法名称相同的类名,则将调用这些方法而不是这种特殊技术。例如,调用an_array.hash将为您提供数组的散列代码,而不是散列的第一个实例。
在这方面,一种更安全的技术更类似于我认为您正在尝试做的事情。它实际上使用类对象,您可以使用它来覆盖其他方法:
class Array
def add(class_object)
class << self
define_method class_object.name do
find do |element|
element.is_a? class_object
end
end
end
end
end这将直接在数组的实例上定义新方法。例如:
an_array = [Array, Hash, Dragon].map &:new
an_array.add Hash
an_array.hash #=> {}如果这个答案不包括一个解决方案,它至少应该引导你更接近!
https://stackoverflow.com/questions/5408230
复制相似问题