2014-03-26 2 views

ответ

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 

Для случая использования вы описываете, Ruby 2.0 введен refinements, который вы можете использовать, как показано ниже. Обратите внимание, что using Модуль внутри другого модуля невозможен в Ruby 2.0, но находится в Ruby 2.1. Поэтому для использования модуля Magic внутри SomeModule вам понадобится 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

КАМ, мне нужна, чтобы получить доступ к 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 

Ваш оригинальный пример определяет новый класс под названием Fixnum в Magic (Magic::Fixnum). Он не касается глобального Fixnum. Ответ, который вы отправили, где вы сказали ::Fixnum, изменяет глобальный класс Fixnum.

Смежные вопросы