Forum: Ruby Fixnums can have instance variables? Cool.

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
unknown (Guest)
on 2005-12-30 09:49
(Received via mailing list)
This really surprises me:

3.instance_variable_set("@unbelievable", "believe it!")

puts 3.instance_variable_get("@unbelievable")		# -> "believe it!"

which led me to:

class Fixnum
   attr_accessor :note
end

13.note = "a baker's dozen"
25.note = "5 squared"

notes = [13, 21, 25].collect { |x| x.note }		# ["a baker's dozen",
nil, "5 squared"]

Am I the only person with their jaw on the ground?

Gary W.
Gregory B. (Guest)
on 2005-12-30 10:40
(Received via mailing list)
On 12/30/05, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:

> class Fixnum
>    attr_accessor :note
> end

> Am I the only person with their jaw on the ground?

that is very cool.

('a'..'z').each_with_index { |letter,index| index.note = letter }

That was my first little random hack, but I imagine there are more
possibilities here :)
Chris P. (Guest)
on 2005-12-30 10:59
(Received via mailing list)
On 12/30/05, removed_email_address@domain.invalid 
<removed_email_address@domain.invalid> wrote:
> Am I the only person with their jaw on the ground?

When I discovered this, what surprised me was not so much that you
could do this, but that can do this _even_though_ you can't give them
singleton methods (or access their singleton classes).

I just assumed the reason was because the singleton classes are stored
in some structure that immediate values don't have, but that instance
variables are stored separately in some other way.  (I never looked at
the interpreter source to verify this, though.)

So the question in my mind:  Is there a reason we couldn't do that
with ints, too?

Chris
Pete (Guest)
on 2005-12-30 12:16
(Received via mailing list)
class Object
   def foo
     "foo"
   end
   class <<self
     def bar
       "bar"
     end
   end
end

examples:

"Some string".foo
-> "foo"

Bignum.bar
-> "bar
Lyndon S. (Guest)
on 2005-12-30 13:10
(Received via mailing list)
I'm pretty sure some of the crusty old rubyists here would say, Not
being
surprised about this is a first step towards ruby master... :-)
Chris P. (Guest)
on 2005-12-30 13:42
(Received via mailing list)
On 12/30/05, Pete <removed_email_address@domain.invalid> wrote:
> class Object
>    def foo
>      "foo"
>    end
>    class <<self
>      def bar
>        "bar"
>      end
>    end
> end

No, I meant giving the Fixnums themselves singleton methods, like this:

irb(main):001:0> a = 'hello'
=> "hello"
irb(main):002:0> def a.hi
irb(main):003:1>   'hi'
irb(main):004:1> end
=> nil
irb(main):005:0> a.hi
=> "hi"
irb(main):006:0> b = 5
=> 5
irb(main):007:0> def b.howdy
irb(main):008:1>   'howdy'
irb(main):009:1> end
TypeError: can't define singleton method "howdy" for Fixnum
        from (irb):7
irb(main):010:0> :(  Why not??


So I can do it for a string, but not a fixnum (or any other immediate
object).

That's what surprised me.  You can have instance variables for 5, but
not singleton methods for 5.  (Of course you can have methods for 5,
but if 5 responds to it, then 6 does, too.)

Cheers,

Chris
J. Ryan S. (Guest)
on 2005-12-30 17:40
(Received via mailing list)
Quoting http://www.rubygarden.org/faq/entry/show/83 :

"Fixnums, Symbols, true, nil, and false are implemented as immediate
values. With immediate values, variables hold the objects themselves,
rather than references to them.

Singleton methods cannot be defined for such objects. Two Fixnums of
the same value always represent the same object instance, so (for
example) instance variables for the Fixnum with the value "one" are
shared between all the "ones" is the system. This makes it impossible
to define a singleton method for just one of these."

~ ryan ~
Chris P. (Guest)
on 2005-12-30 23:12
(Received via mailing list)
On 12/30/05, J. Ryan S. <removed_email_address@domain.invalid> wrote:
> Two Fixnums of
> the same value always represent the same object instance, so (for
> example) instance variables for the Fixnum with the value "one" are
> shared between all the "ones" is the system.

Makes sense so far.  Then we get this:

> This makes it impossible
> to define a singleton method for just one of these."

What!?  The implementation makes it impossible, not the fact that
every 1 in the system refers to the same object.  The constant
"Object" refers to the same object (the Object class) every time I
write it; this certainly doesn't prevent one from writing singleton
methods for it.

I'm not sure what the original author of that was trying to say, but I
think the real answer is just that, for whatever implementation
reasons (most likely for the sake of optimization), immediate objects
can't have singleton methods.

Again, my guess is that the choice was make to store singleton methods
(or the pointer to the singleton class) in some "ruby object" struct
that immediate values don't have.  But what I find surprising (going
all the way back to the beginning :) is that, given this, we can still
define instance variables.  The reason for this must be that instance
variables are stored elsewhere (not in this "ruby object" struct, but
in some other data store).  But this seems an odd choice.  I would
have thought that both the klass pointer (as I think they call it) and
the instance variables are stored in that struct.  Maybe GC had
something to do with this design... I can't say more without looking
at the source.

(Isn't this usually where Guy steps in with an email consisting of 4
words and the exact lines of the interpreter code?  :)

Chris
unknown (Guest)
on 2005-12-30 23:51
(Received via mailing list)
On Dec 30, 2005, at 4:10 PM, Chris P. wrote:
> I'm not sure what the original author of that was trying to say, but I
> think the real answer is just that, for whatever implementation
> reasons (most likely for the sake of optimization), immediate objects
> can't have singleton methods.

Without thinking too hard about it and without looking at the
source code, I would guess that it is not supported to avoid
the overhead of a method search for individual objects.  You
still have to do the method search for the class and as such
you can extend the class but the search for a per/object
method is avoided.


Gary W.
ts (Guest)
on 2005-12-31 12:14
(Received via mailing list)
>>>>> "C" == Chris P. <removed_email_address@domain.invalid> writes:

C> (Isn't this usually where Guy steps in with an email consisting of 4
C> words and the exact lines of the interpreter code?  :)

 [ruby-talk:17321]

 :-)


Guy Decoux
Ross B. (Guest)
on 2005-12-31 13:30
(Received via mailing list)
On Fri, 30 Dec 2005 07:46:17 -0000, <removed_email_address@domain.invalid> 
wrote:

> end
>
> 13.note = "a baker's dozen"
> 25.note = "5 squared"
>
> notes = [13, 21, 25].collect { |x| x.note }		# ["a baker's dozen", nil,
> "5 squared"]
>
> Am I the only person with their jaw on the ground?
>

:D That one got me, too. I kind of hinted at it in some nuby code I
wrote
(http://roscopeco.co.uk/code/noob/bitwise.html). Also check out:

irb(main):001:0> class Symbol
irb(main):002:1> attr_accessor :too
irb(main):003:1> end
=> nil
irb(main):004:0> :foo.too
=> nil
irb(main):005:0> :foo.too = 66
=> 66
irb(main):006:0> :foo.too
=> 66

This struck me as pretty cool, too:

irb(main):007:0> SomethingElse = Symbol
=> Symbol
irb(main):008:0> :foo.is_a? SomethingElse
=> true

God, Ruby is *good*
Barca J. (Guest)
on 2008-01-05 17:07
>
> class Fixnum
>    attr_accessor :note
> end
>
> 13.note = "a baker's dozen"
> 25.note = "5 squared"
>
> notes = [13, 21, 25].collect { |x| x.note }    # ["a baker's dozen",
> nil, "5 squared"]
>


It's really cool.
Jason R. (Guest)
on 2008-01-05 17:15
(Received via mailing list)
Welcome to Monkey Patching! This is how ActiveResource gives you things
like:

4.days.ago

"some string".underscore

and the like.

It's one of the many things that makes Ruby code very fun to write.

Jason
Gary W. (Guest)
on 2008-01-05 17:33
(Received via mailing list)
On Jan 5, 2008, at 10:15 AM, Jason R. wrote:

> It's one of the many things that makes Ruby code very fun to write
Actually it is a bit different.  Monkey patching is just adding
methods to classes. Fixnum and String in your examples.

Instance variables on Fixnums (or Symbols or Nil) is different.
It is a good example of uniformity in Ruby but I'm hard pressed
to think of a nice use case for the feature.

Gary W.
Sander L. (Guest)
on 2008-01-05 22:56
(Received via mailing list)
On Jan 5, 2008 4:32 PM, Gary W. <removed_email_address@domain.invalid> wrote:
> Actually it is a bit different.  Monkey patching is just adding
> methods to classes. Fixnum and String in your examples.
>
> Instance variables on Fixnums (or Symbols or Nil) is different.
> It is a good example of uniformity in Ruby but I'm hard pressed
> to think of a nice use case for the feature.
>
> Gary W.
You can use it to cache the result of method calls.

class Fixnum
 def factorial
  @factorial ||= self * (self-1).factorial
 end
end
0.instance_variable_set('@factorial',1)
This topic is locked and can not be replied to.