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