Reputation: 3419
Why doesn't this work?
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
Upvotes: 0
Views: 73
Reputation: 3092
If you want your modifications to Fixnum
to only apply certain places, you can use 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
Your original example defines an new class called Fixnum
within Magic
(Magic::Fixnum
). It does not touch the global Fixnum
. The response you posted where you said ::Fixnum
modifies the global Fixnum
class.
Upvotes: 0
Reputation: 3055
The answer you posted yourself is actually changing Fixnum
globally, which is not what you want. That is, with your solution:
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
For the use case you describe, Ruby 2.0 introduced refinements, which you can use like below. Please note that using
a Module inside another Module is not possible in Ruby 2.0, but is in Ruby 2.1. So to use the Magic
module inside SomeModule
you will require Ruby 2.1. This might be a problem if you are using Windows since you will have to compile 2.1 yourself, the Windows binaries and installer are still at 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
Upvotes: 5
Reputation: 3419
OK, I need to access the Fixnum
class at toplevel, the code should be:
module Magic
class ::Fixnum
def div2(other)
self.to_f / other
end
alias :"/" :div2
end
end
This works!
Upvotes: 0