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:

  1. 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 
  2. you define roundup singleton method of object fixnum, call instance method of instances of fixnum. solution: make roundup 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 
  3. the ruby language specification not guarantee there is fixnum class. guarantees there integer class, , allows different implementations may provide implementation-specific subclasses. (e.g. yarv has fixnum , bignum subclasses of integer.) since add method fixnum, won't work other integers, aren't fixnums. , since range of fixnums 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 of integer:

    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

Popular posts from this blog

html - Firefox flex bug applied to buttons? -

html - Missing border-right in select on Firefox -

c# - two queries in same method -