Singleton methods : when are they not permitted?

irb(main):025:0> x = :any
=> :any
irb(main):026:0> def x.include(obj); true; end
TypeError: can't define singleton method "include" for Symbol
        from (irb):26

Why no singleton methods on Symbol?

Are there other objects that are also not allowed to have singleton methods?

Thanks!

itsme213 wrote:

Why no singleton methods on Symbol?

Are there other objects that are also not allowed to have singleton methods?

Singleton methods can not be defined for "immediate" Objects. Immediate Objects are stored directly by their id which means they are very cheap to use.

Immediate objects include all Fixnums, Symbols, true, false and nil (but note that def true.foo; end will silently add the method directly to TrueClass because there is guaranteed to be only one instance, true, for it.)

You can also not add methods to Floats and Bignums (this is for consistency with Fixnums), but this can be changed by overriding Numeric#singleton_method_added.

It also seems not to be possible to directly add methods to literals like this: (Not sure why -- maybe Ruby optimizes literals?)

irb(main):014:0> def ("x").foo; end
SyntaxError: compile error
(irb):14: can't define singleton method for literals

However this can be worked around trivially by using an expression instead:

irb(main):015:0> def (("x")).foo; end
=> nil

itsme213 schrieb:

irb(main):025:0> x = :any
=> :any
irb(main):026:0> def x.include(obj); true; end
TypeError: can't define singleton method "include" for Symbol
       from (irb):26

Why no singleton methods on Symbol?

Are there other objects that are also not allowed to have singleton methods?

Yes you can't define singleton methods for Fixnums either - originally
the answers was all so called "immediate" objects (Fixnums, Symbols
nil,true, and false) which are Object existing outside of the garbage
collector but Matz implemented special singleton methods (+ singleton
class) for nil,true and false. For exmple, both

def nil.fine() end

class << true
    Love = :forever
end

are okay.

Interestingly enough you can define instance variables
for all immediate values - for example

class Object
  def you
    p @you
  end
end

:me.instance_variable_set(:@you, :you)
0.instance_variable_set(:@you, -1)

:me.you # :you
0.you # -1

/Christoph

Errrr. So what's the difference between

def ("x").foo; end

and

def (("x")).foo; end

Why do the extra parens make the parser treat it differently? My head hurts.

Francis Hwang

···

On Nov 30, 2004, at 6:12 PM, Florian Gross wrote:

It also seems not to be possible to directly add methods to literals like this: (Not sure why -- maybe Ruby optimizes literals?)

irb(main):014:0> def ("x").foo; end
SyntaxError: compile error
(irb):14: can't define singleton method for literals

However this can be worked around trivially by using an expression instead:

irb(main):015:0> def (("x")).foo; end
=> nil

Florian Gross schrieb:

itsme213 wrote:

Why no singleton methods on Symbol?

Are there other objects that are also not allowed to have singleton methods?

Singleton methods can not be defined for "immediate" Objects. Immediate Objects are stored directly by their id which means they are very cheap to use.

Immediate objects include all Fixnums, Symbols, true, false and nil (but note that def true.foo; end will silently add the method directly to TrueClass because there is guaranteed to be only one instance, true, for it.)
You can also not add methods to Floats and Bignums (this is for consistency with Fixnums), but this can be changed by overriding Numeric#singleton_method_added

(Miss)Applying syllogistic logic you can add singleton methods
to Floats or Singletons you just have do deal with the exception
either by changing Numeric#singleton_method_added or simply
catching the exception

x = 2.0
class << x
def bla;end
rescue
end

x.bla

/Christoph

Hi --

> It also seems not to be possible to directly add methods to literals
> like this: (Not sure why -- maybe Ruby optimizes literals?)
>
> irb(main):014:0> def ("x").foo; end
> SyntaxError: compile error
> (irb):14: can't define singleton method for literals
>
> However this can be worked around trivially by using an expression
> instead:
>
> irb(main):015:0> def (("x")).foo; end
> => nil

Errrr. So what's the difference between

def ("x").foo; end

and

def (("x")).foo; end

Why do the extra parens make the parser treat it differently? My head
hurts.

I think the difference is that (("x")) causes the expression inside
the inner parens to be evaluated first, so by the time it's seen by
def, it isn't a literal but the result of an evaluated expression. So
def treats it as if it were seeing:

  a = "x"
  def (a).foo ...

At least that's my reading of it.

David

···

On Wed, 1 Dec 2004, Francis Hwang wrote:

On Nov 30, 2004, at 6:12 PM, Florian Gross wrote:

--
David A. Black
dblack@wobblini.net

Francis Hwang schrieb:

It also seems not to be possible to directly add methods to literals like this: (Not sure why -- maybe Ruby optimizes literals?)

Pardon my igmorance but what is a literal?

Errrr. So what's the difference between

def ("x").foo; end

and

def (("x")).foo; end

Why do the extra parens make the parser treat it differently? My head hurts.

Mine too - I find these error messages rather missleading
after all both

("x") == "x"

(("x")) == "x"

evalute to true

/Christoph

···

On Nov 30, 2004, at 6:12 PM, Florian Gross wrote:

Hi --

···

On Wed, 1 Dec 2004, Christoph wrote:

Francis Hwang schrieb:

>
> On Nov 30, 2004, at 6:12 PM, Florian Gross wrote:
>
>> It also seems not to be possible to directly add methods to literals
>> like this: (Not sure why -- maybe Ruby optimizes literals?)
>
Pardon my igmorance but what is a literal?

> Errrr. So what's the difference between
>
> def ("x").foo; end
>
> and
>
> def (("x")).foo; end
>
> Why do the extra parens make the parser treat it differently? My head
> hurts.

Mine too - I find these error messages rather missleading
after all both

("x") == "x"

(("x")) == "x"

evalute to true

So does:

  a = "x"
  a == "x"

but still, during parsing a bare identifier like 'a' and a literal
like '"x"' are not treated the same way.

David

--
David A. Black
dblack@wobblini.net

* David A. Black <dblack@wobblini.net> [2004-12-01 10:14:40 +0900]:

  a = "x"
  def (a).foo ...

My confusion is that I don't see the value in this.
I cannot access the 'just defined method foo' of "x" anyway.

Let's see..., "x".foo, oh no, wait. "x" is different than "x".
I give.

···

--
Jim Freeze
Code Red. Code Ruby

"David A. Black" <dblack@wobblini.net> schrieb im Newsbeitrag
news:Pine.LNX.4.44.0411301808310.27136-100000@wobblini...

Hi --

> Francis Hwang schrieb:
>
> >
> >
> >> It also seems not to be possible to directly add methods to

literals

> >> like this: (Not sure why -- maybe Ruby optimizes literals?)
> >
> Pardon my igmorance but what is a literal?
>
> > Errrr. So what's the difference between
> >
> > def ("x").foo; end
> >
> > and
> >
> > def (("x")).foo; end
> >
> > Why do the extra parens make the parser treat it differently? My

head

> > hurts.
>
> Mine too - I find these error messages rather missleading
> after all both
>
> ("x") == "x"
>
> (("x")) == "x"
>
> evalute to true

So does:

  a = "x"
  a == "x"

but still, during parsing a bare identifier like 'a' and a literal
like '"x"' are not treated the same way.

You can view "x" as an object constructor (much similar to 1, {1=>2}
etc.). Different from 1 "x" creates new instances every time it is
executed:

09:24:22 [robert.klemme]: ruby -e '10.times { p "x".id }'
134690520
134690496
134690472
134690448
134690424
134690400
134690376
134690352
134690328
134690304

That explains why a) it doesn't make sense to do 'def "x".foo()...end'
(regardless of the number of brackets around "x") and b) Ruby issues the
warning / error message.

Kind regards

    robert

···

On Wed, 1 Dec 2004, Christoph wrote:
> > On Nov 30, 2004, at 6:12 PM, Florian Gross wrote:

You can view "x" as an object constructor (much similar to 1, {1=>2}
etc.). Different from 1 "x" creates new instances every time it is
executed:
That explains why a) it doesn't make sense to do 'def "x".foo()...end'
(regardless of the number of brackets around "x") and b) Ruby issues the
warning / error message.

I'm sure I am missing something.

a = "x"
def a.foo; end
b = a
b.foo

Have I not defined a singleton method on a literal?

"itsme213" <itsme213@hotmail.com> schrieb im Newsbeitrag
news:PQkrd.64867$g21.12722@fe1.texas.rr.com...

> You can view "x" as an object constructor (much similar to 1,

{1=>2}

> etc.). Different from 1 "x" creates new instances every time it is
> executed:
> That explains why a) it doesn't make sense to do 'def "x".foo()...end'
> (regardless of the number of brackets around "x") and b) Ruby issues

the

> warning / error message.

I'm sure I am missing something.

a = "x"
def a.foo; end
b = a
b.foo

Have I not defined a singleton method on a literal?

You have not. You defined a singleton method on a string instance that
represents the sequence "x". If you like you can view it that way that
the literal "x" is not directly accessible. It just creates a string
instance with sequence "x" every time it is evaluated:

15:51:21 [c]: ruby -e '10.times { p "x".id }'
134690524
134690500
134690476
134690452
134690428
134690404
134690380
134690356
134690332
134690308

Kind regards

    robert

> Have I not defined a singleton method on a literal?

You have not. You defined a singleton method on a string instance that
represents the sequence "x". If you like you can view it that way that
the literal "x" is not directly accessible. It just creates a string
instance with sequence "x" every time it is evaluated:

Ah. Subtle. Thanks (assuming I've got it!). Would this re-phrasing be the
right idea?

A literal (I'll use the term 'value' object as a generalization) is a
virtual object that you cannot access or manipulate. Every conceivable value
object already exists before the first line of your code is run. What you
can create, access, and manipulate are instances that represent, by various
encodings, references to a given value object.

For immediate objects, these referencing instances use encodings that
directly share the same object_id.
e.g.
:a # reference to unique virtual symbol :a
:a.object_id == :a.object_id #=> true
:a == :a #=> true, obviously

For all other value objects, those referencing instances have "==" defined
so that references to the same value object compare as identical.
"x" # reference to unique virtual string "x"
"x".object_id == "x".object_id #=> false
"x" == "x" #=> true

"itsme213" <itsme213@hotmail.com> schrieb im Newsbeitrag
news:u_mrd.59121$KQ2.55810@fe2.texas.rr.com...

> > Have I not defined a singleton method on a literal?
>
> You have not. You defined a singleton method on a string instance

that

> represents the sequence "x". If you like you can view it that way

that

> the literal "x" is not directly accessible. It just creates a string
> instance with sequence "x" every time it is evaluated:

Ah. Subtle. Thanks (assuming I've got it!). Would this re-phrasing be

the

right idea?

A literal (I'll use the term 'value' object as a generalization) is a
virtual object that you cannot access or manipulate. Every conceivable

value

object already exists before the first line of your code is run. What

you

can create, access, and manipulate are instances that represent, by

various

encodings, references to a given value object.

I prefer to view a literal as a special kind of expression that yields an
instance on each execution. Whether this is always the same instance (as
for symbols, Fixnum and surprisingly also for Bignum and Regexp) or
whether it's a different instance (as for strings, arrays and hashes)
depends on the literal.

For immediate objects, these referencing instances use encodings that
directly share the same object_id.
e.g.
:a # reference to unique virtual symbol :a
:a.object_id == :a.object_id #=> true
:a == :a #=> true, obviously

For all other value objects, those referencing instances have "=="

defined

so that references to the same value object compare as identical.
"x" # reference to unique virtual string "x"
"x".object_id == "x".object_id #=> false
"x" == "x" #=> true

I think you got it. I was just irritated by you usage of "encoding" as I
associate this usually with character encodings such as ISO-8859, UTF-8,
UTF-16 and the like.

The crucial part is to be aware of the fact that there might or might not
be instances created and that this has performance implications. That's
why I usually define class constants for certain strings like this

class Foo
  BAR = "foo".freeze

  def doit(x)
    if BAR == x
      "yes"
    else
      "no"
    end
  end
end

Kind regards

    robert

That regexps are always the same surprised me also, but it is nice. So it is
not optimization to extract a regexp into a constant instead of writing it in
the loop.

(Btw: Always when I'm trying to optimze something in ruby, it gets slower. Ruby
follows exactly my mindset when programming, and when I try to change my mind
on how the computer actually works it out, I'm running in the wrong
direction.:wink:

irb(main):005:0> 2.times do |i| puts /abc/.id end
538420744
538420744
=> 2

But it can't always be true

irb(main):006:0> 2.times do |i| puts /abc#{i}/.id end
538396754
538396704
=> 2

Or maybe one should clarify it such, that a regexp with interpolation is no
longer a literal.

Regards,

Brian

···

On Thu, 2 Dec 2004 19:12:43 +0900 "Robert Klemme" <bob.news@gmx.net> wrote:

I prefer to view a literal as a special kind of expression that yields an
instance on each execution. Whether this is always the same instance (as
for symbols, Fixnum and surprisingly also for Bignum and Regexp) or
whether it's a different instance (as for strings, arrays and hashes)
depends on the literal.

--
Brian Schröder
http://www.brian-schroeder.de/

"Brian Schröder" <ruby@brian-schroeder.de> schrieb im Newsbeitrag
news:20041202123358.431849d2@black.wg...

> I prefer to view a literal as a special kind of expression that yields

an

> instance on each execution. Whether this is always the same instance

(as

> for symbols, Fixnum and surprisingly also for Bignum and Regexp) or
> whether it's a different instance (as for strings, arrays and hashes)
> depends on the literal.

That regexps are always the same surprised me also, but it is nice. So

it is

not optimization to extract a regexp into a constant instead of writing

it in

the loop.

Except you need some interpolation. :slight_smile:

(Btw: Always when I'm trying to optimze something in ruby, it gets

slower. Ruby

follows exactly my mindset when programming, and when I try to change my

mind

on how the computer actually works it out, I'm running in the wrong
direction.:wink:

:slight_smile:

irb(main):005:0> 2.times do |i| puts /abc/.id end
538420744
538420744
=> 2

But it can't always be true

irb(main):006:0> 2.times do |i| puts /abc#{i}/.id end
538396754
538396704
=> 2

Or maybe one should clarify it such, that a regexp with interpolation is

no

longer a literal.

But

2.times do |i| puts /abc#{i}/o.id end

135012888
135012888
=> 2

Note the usage of flag "o".

Kind regards

    robert

···

On Thu, 2 Dec 2004 19:12:43 +0900 > "Robert Klemme" <bob.news@gmx.net> wrote:

[snip]
But

>> 2.times do |i| puts /abc#{i}/o.id end
135012888
135012888
=> 2

Note the usage of flag "o".

Kind regards

    robert

Interesting, but what is the use case for this? It seems to be quite dangerous
because it makes code really difficult to understand.

E.g. The causual reader would expect this to yield nil, 0, nil.

3.times do | i | puts /#{i}/o =~ '1' end

nil
nil
nil
=> 3

I shall read my pickaxe again :wink:

Regards,

Brian

···

On Thu, 2 Dec 2004 21:27:43 +0900 "Robert Klemme" <bob.news@gmx.net> wrote:

--
Brian Schröder
http://www.brian-schroeder.de/

"Brian Schröder" <ruby@brian-schroeder.de> schrieb im Newsbeitrag
news:20041202141630.4a975ff1@black.wg...

> [snip]
> But
>
> >> 2.times do |i| puts /abc#{i}/o.id end
> 135012888
> 135012888
> => 2
>
> Note the usage of flag "o".
>
> Kind regards
>
> robert
>

Interesting, but what is the use case for this? It seems to be quite

dangerous

because it makes code really difficult to understand.

It's an optimization flag. It's for those cases where you need
interpolation in a regexp but you know it will never change again. This
is usual in little scripts, like

fake-grep.rb

rx = ARGV.shift
while ( line = gets )
  puts line if /#{rx}/o =~ line
end

I think Ruby inherited this flag from P**l.

Note: of course you can achieve the same with this little change:

rx = /#{ARGV.shift}/
while ( line = gets )
  puts line if rx =~ line
end

E.g. The causual reader would expect this to yield nil, 0, nil.

> 3.times do | i | puts /#{i}/o =~ '1' end
nil
nil
nil
=> 3

I shall read my pickaxe again :wink:

:slight_smile:

Regards

    robert

···

On Thu, 2 Dec 2004 21:27:43 +0900 > "Robert Klemme" <bob.news@gmx.net> wrote:

Robert Klemme wrote:

I think Ruby inherited this flag [/o] from P**l.

Is Perl inheritance something to be ashamed of nowadays?

"Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag
news:318mrsF375j5iU2@individual.net...

Robert Klemme wrote:

> I think Ruby inherited this flag [/o] from P**l.

Is Perl inheritance something to be ashamed of nowadays?

Who said it was Perl? :wink:

Dunno, but I don't like to be remembered of that language. - It's so -
so - cryptic.
:slight_smile:

    robert