2011-03-23 36 views
0

编程,我试图让一个通用的方法:元/动态/通用在红宝石

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) 

其中方法1是类的名称。

另外,我需要一个关于元编程和动态/泛型编程的完整教程。

+1

对于元编程尝试http://pragprog.com/titles/ppmetr/metaprogramming-ruby – blu 2011-03-23 16:12:05

+0

感谢您的帮助 – maxiperez 2011-03-23 17:41:19

回答

4

我不确定你想要从你的例子中做什么。作为一般规则,在Ruby中,您不检查类型。它是动态类型的原因:您可以编写适用于任何碰巧支持您的代码调用方法的对象的代码。

从我可以从你的意见告诉,你想扩展类Array所以,当你调用像an_array.pack阵列上的方法,该阵列中搜索的Pack一个实例并返回。 Ruby有一种方法,只要发现方法不存在,称为Module#method_missing。例如,如果我随机决定调用4.to_dragon(magic: 4, height: 700),则Ruby解释器将尝试将to_dragon作为在Fixnum(数字类型)继承链中某些类或模块上定义的公共方法。假设您没有对链条做过任何奇怪的事情,我们会通过以下参数调用method_missing对象4[: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 #=> {} 

如果此答案不包括解决方案,它应该至少引导您更接近!

+0

方法的名称是类的名称。例如我将一个包和一个产品保存在一个数组中,所以我使用array.pack或array.product我可以问参数对象is_a?(Class),但我想制作一个接受任何东西的泛型方法。如果我的意见不明确,请回​​答我。 – maxiperez 2011-03-28 15:12:37

+0

有一种有趣的方式可以通过元编程实现,我现在将添加它。 – Tom 2011-03-29 00:03:24