On 2/12/08, Clifford Heath <no / spam.please.net> wrote:
> Folk,
>
> Refer to <http://www.ruby-forum.com/topic/96434> for the context.
>
> I'm doing some metaprogramming where I wanted folk to be able to
> subclass Integer, for example: "class Year < Integer; ... end".
> You can't do this with Integer in a sensible way, because Integers
> are value types in Ruby, and don't support the new() method.
>
> However, I came up with the following cunning bit of code, which
> seems to work. The code is also here: <http://pastie.caboo.se/150741>.
> I use BasicObject from Facets, which isn't the only way to get that,
> you might have 1.9 for example :-).
>
> Please comment,

I don't think this does what you think:

require 'rubygems'
require "facets/basicobject" unless Object.const_defined? :BasicObject

class Integer
 class BoxedInteger < BasicObject
   private
   attr_accessor :__value # !> private attribute?

   def self.new(*a)
     super *a # !> `*' interpreted as argument prefix
   end

   def initialize(v)
     @__value = v.to_i
   end

   def method_missing(meth, *args, &block)
     __value.send meth, *args, &block
   end
 end

 def self.inherited(subclass)
   def subclass.new(i)
     BoxedInteger.new(i)
   end
 end
end

class Year < Integer
end

Year.new(2008).class # => Fixnum
Year.new(2008) == 2008 # => true

There's a lot of good advice in the referenced thread from experienced
Rubyists about why this is not such a good idea in general.

Ruby doesn't require forcing classes to inherit in order to conform to
a type system. Going through hoops to do so is a symptom of thinking
in Java or C++ rather than in Ruby.

-- 
Rick DeNatale

My blog on Ruby
http://talklikeaduck.denhaven2.com/