|
| Author |
Message |
| itsme213 |
Posted: Tue Nov 30, 2004 11:57 pm |
|
|
|
|
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!
|
|
| Back to top |
|
| Florian Gross |
Posted: Tue Nov 30, 2004 11:57 pm |
|
|
|
|
itsme213 wrote:
Quote: 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
|
|
| Back to top |
|
| Christoph |
Posted: Wed Dec 01, 2004 3:46 am |
|
|
|
|
Florian Gross schrieb:
Quote: 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
|
|
| Back to top |
|
| Christoph |
Posted: Wed Dec 01, 2004 3:46 am |
|
|
|
|
itsme213 schrieb:
Quote: 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
|
|
| Back to top |
|
| Guest |
Posted: Wed Dec 01, 2004 6:47 am |
|
|
|
|
* David A. Black <dblack@wobblini.net> [2004-12-01 10:14:40 +0900]:
Quote: 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
|
|
| Back to top |
|
| itsme213 |
Posted: Wed Dec 01, 2004 4:54 pm |
|
|
|
|
Quote: 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?
|
|
| Back to top |
|
| Robert Klemme |
Posted: Wed Dec 01, 2004 4:54 pm |
|
|
|
|
"itsme213" <itsme213@hotmail.com> schrieb im Newsbeitrag
news:PQkrd.64867$g21.12722@fe1.texas.rr.com...
Quote: 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
|
|
| Back to top |
|
| itsme213 |
Posted: Wed Dec 01, 2004 5:45 pm |
|
|
|
|
Quote: 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
|
|
| Back to top |
|
| Robert Klemme |
Posted: Thu Dec 02, 2004 11:21 am |
|
|
|
|
"itsme213" <itsme213@hotmail.com> schrieb im Newsbeitrag
news:u_mrd.59121$KQ2.55810@fe2.texas.rr.com...
Quote:
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.
Quote: 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
|
|
| Back to top |
|
| Brian Schröder |
Posted: Thu Dec 02, 2004 11:55 am |
|
|
|
|
On Thu, 2 Dec 2004 19:12:43 +0900
"Robert Klemme" <bob.news@gmx.net> wrote:
Quote: 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.
(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.;)
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
--
Brian Schröder
http://www.brian-schroeder.de/
|
|
| Back to top |
|
| Robert Klemme |
Posted: Thu Dec 02, 2004 5:24 pm |
|
|
|
|
"Brian Schröder" <ruby@brian-schroeder.de> schrieb im Newsbeitrag
news:20041202123358.431849d2@black.wg...
Quote: 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.
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. :-)
Quote: (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.
:-)
Quote: 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
Quote: 2.times do |i| puts /abc#{i}/o.id end
135012888
135012888
=> 2
Note the usage of flag "o".
Kind regards
robert
|
|
| Back to top |
|
| Brian Schröder |
Posted: Thu Dec 02, 2004 6:16 pm |
|
|
|
|
On Thu, 2 Dec 2004 21:27:43 +0900
"Robert Klemme" <bob.news@gmx.net> wrote:
Quote: [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.
Quote: 3.times do | i | puts /#{i}/o =~ '1' end
nil
nil
nil
=> 3
I shall read my pickaxe again ;)
Regards,
Brian
--
Brian Schröder
http://www.brian-schroeder.de/
|
|
| Back to top |
|
| Robert Klemme |
Posted: Thu Dec 02, 2004 6:40 pm |
|
|
|
|
"Brian Schröder" <ruby@brian-schroeder.de> schrieb im Newsbeitrag
news:20041202141630.4a975ff1@black.wg...
Quote: On Thu, 2 Dec 2004 21:27: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.
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
Quote: 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
:-)
Regards
robert
|
|
| Back to top |
|
| Florian Gross |
Posted: Thu Dec 02, 2004 7:23 pm |
|
|
|
|
Robert Klemme wrote:
Quote: I think Ruby inherited this flag [/o] from P**l.
Is Perl inheritance something to be ashamed of nowadays?
|
|
| Back to top |
|
| Robert Klemme |
Posted: Thu Dec 02, 2004 8:33 pm |
|
|
|
|
"Florian Gross" <flgr@ccan.de> schrieb im Newsbeitrag
news:318mrsF375j5iU2@individual.net...
Quote: 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? ;-)
Dunno, but I don't like to be remembered of that language. - It's so -
so - cryptic.
:-)
robert
|
|
| Back to top |
|
|