2014-03-26 46 views
0

为什么不能正常工作?如何在ruby中为一个模块覆盖一个类?

module Magic 
    class Fixnum 
    def div2(other) 
     self.to_f/other 
    end 

    alias :"/" :div2 
    end 
end 

module SomeModule 
    include Magic 

    1/4 == 0.25 #should be true in here 
end 

1/4 == 0.25 #should be false everywhere else 
+0

一个细节:'self.to_f'确定,但'to_f'就足够了。 –

回答

5

您发布的答案实际上是全球变化的Fixnum,这不是您想要的。也就是说,你的解决方案:

module Magic 
    class ::Fixnum 
    def div2(other) 
     self.to_f/other 
    end 

    alias :"/" :div2 
    end 
end 

# Yields 0.25 instead of expected 0. 
# This line should not be affected by your Fixnum change, but is. 
1/4 

对于您所描述的用例,红宝石2.0引入refinements,你可以使用如下。请注意,using另一个模块中的模块在Ruby 2.0中是不可能的,但在Ruby 2.1中是不可能的。因此,要使用SomeModule中的Magic模块,您需要使用Ruby 2.1。如果您使用的是Windows,这可能会造成问题,因为您必须自己编译2.1,Windows二进制文件和安装程序仍然在2.0。

module Magic 
    refine Fixnum do 
    def /(other) 
     self.to_f/other 
    end 
    end 
end 

1/4 # => 0 
using Magic 
1/4 # => 0.25 
0

OK,我需要在顶层访问Fixnum类,代码应该是:

module Magic 
    class ::Fixnum 
    def div2(other) 
     self.to_f/other 
    end 

    alias :"/" :div2 
    end 
end 

这工作!

0

如果你想让你的修改Fixnum只适用于某些地方,你可以使用refinements

module Magic 
    refine Fixnum do 
    def foo 
     "Hello" 
    end 
    end 
end 

class SomeClass 
    using Magic 

    10.foo # => "Hello" 

    def initialize 
    10.foo # => "Hello" 
    end 
end 

10.foo # Raises NoMethodError 

你原来的例子定义内MagicMagic::Fixnum)称为Fixnum类。它不会触及全球Fixnum。您发布的回复信息::Fixnum修改了全球Fixnum课程。

相关问题