ruby - Why can't I extend the Fixnum class in a module and use it? -
i've created module in extend fixnum class new method. when require
module , try use extended method, returns:
nomethoderror: undefined method `roundup' 13:fixnum
here's module looks like:
module eancontrol # extend fixnum #roundup class fixnum def self.roundup return self if self % 10 == 0 # factor of 10 return self + 10 - (self % 10) # go nearest factor 10 end end # more code... end
this i'm doing:
require 'path_to_module' 12.roundup # => nomethoderror: undefined method `roundup' 13:fixnum
how solve this?
there 3 problems code:
you creating new class
eancontrol::fixnum
, want change existing builtin::fixnum
. solution: explicitly start constant lookup top-level, or, more idiomatically, drop module.module eancontrol class ::fixnum # … end end # although simpler this: class fixnum # … end
you define
roundup
singleton method of objectfixnum
, call instance method of instances offixnum
. solution: makeroundup
instance method:class fixnum def roundup return self if (self % 10).zero? # factor of 10 self + 10 - (self % 10) # go nearest factor 10 end end
the ruby language specification not guarantee there is
fixnum
class. guarantees thereinteger
class, , allows different implementations may provide implementation-specific subclasses. (e.g. yarv hasfixnum
,bignum
subclasses ofinteger
.) since add methodfixnum
, won't work otherinteger
s, aren'tfixnum
s. , since range offixnum
s different different implementations of architectures (e.g. on yarv on 32 bit systems,fixnum
s 31 bit, on 64 bit systems, 63 bit, on jruby, 64 bit), don't know sure numbers method work on , when fail. (e.g.:9223372036854775808.roundup # nomethoderror: undefined method 'roundup' 9223372036854775808:bignum
.) solution: make method instance method ofinteger
:class integer def roundup return self if (self % 10).zero? # factor of 10 self + 10 - (self % 10) # go nearest factor 10 end end
lastly, want suggest @ least using mixin here:
module integerwithroundup def roundup return self if (self % 10).zero? # factor of 10 self + 10 - (self % 10) # go nearest factor 10 end end class integer include integerwithroundup end
now, if else debugs code, , wonders roundup
method comes from, there clear trace in ancestry chain:
12.method(:roundup).owner # => integerwithroundup
even better use refinement, way monkeypatch doesn't pollute global namespace:
module integerwithroundup module roundup def roundup return self if (self % 10).zero? # factor of 10 self + 10 - (self % 10) # go nearest factor 10 end end refine integer include roundup end end 12.roundup # nomethoderror: undefined method `roundup' 12:fixnum using integerwithroundup 12.roundup # => 20
Comments
Post a Comment