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 # … endyou define
roundupsingleton method of objectfixnum, call instance method of instances offixnum. solution: makeroundupinstance method:class fixnum def roundup return self if (self % 10).zero? # factor of 10 self + 10 - (self % 10) # go nearest factor 10 end endthe ruby language specification not guarantee there is
fixnumclass. guarantees thereintegerclass, , allows different implementations may provide implementation-specific subclasses. (e.g. yarv hasfixnum,bignumsubclasses ofinteger.) since add methodfixnum, won't work otherintegers, aren'tfixnums. , since range offixnums different different implementations of architectures (e.g. on yarv on 32 bit systems,fixnums 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