How to get the value of a singleton class?

Here is a sample code:

str = “ABC”
class << str
p self
end

What I get is somthing like “#<Class:#String:0x15d4bb0>”.

If “p str”, there’s an error message:

x.rb:3:in singletonclass': undefined local variable or methodstr’ for
#<Class:#String:0x1625bf8> (NameError)

How can I get the value of str(“ABC”) within the class << str;…;end
block?

Thank you.

Joey

On Fri, Mar 25, 2011 at 1:23 PM, Joey Z. [email protected] wrote:

x.rb:3:in singletonclass': undefined local variable or methodstr’ for
#<Class:#String:0x1625bf8> (NameError)

How can I get the value of str(“ABC”) within the class << str;…;end

your problem is that class << x…end is not a closure

x= 42
class << whatever # I disassociate x and whatever for the general case
x # No Method Error as we are not in a closure here
end

But there is a workaround, an idiom you will find quite often in Ruby
metaprogramming

x=42
class << whatever; self end.module_eval do
p x # Works like charm as this is a closure
end

Now if you were looking for a way to get from a singleton class of an
object to the object itself, I am not sure that this is possible.
I have not yet seen a case where I would have needed it, as I am
constructing my singletons myself;). Would you know such a usecase?
e.g. an API that passes in a singleton class and where it would be
useful to have access to the singlee - I just made this word up, I
guess.

HTH
Robert

Now if you were looking for a way to get from a singleton class of an
object to the object itself, I am not sure that this is possible.
I have not yet seen a case where I would have needed it, as I am
constructing my singletons myself;). Would you know such a usecase?
e.g. an API that passes in a singleton class and where it would be
useful to have access to the singlee - I just made this word up, I
guess.

Thank you for explanation.
The problem is not from a real program, but from my curiosity… I just
read the “singleton class” section of a Ruby book:)

On Fri, Mar 25, 2011 at 2:58 PM, Joey Z. [email protected] wrote:

read the “singleton class” section of a Ruby book:)
Than I am confident that

class << …;self end.module_eval…

will be enough to continue your exploration :slight_smile:

Cheers
R.

On Fri, Mar 25, 2011 at 12:52 PM, Robert D.
[email protected]wrote:

Now if you were looking for a way to get from a singleton class of an
object to the object itself, I am not sure that this is possible.

This should do the trick:

s = “”
=> “”

class << s
def test
1
end
end
=> nil

s.test
=> 1

meta = (class << s; self; end)
=> #<Class:#String:0x83c87ac>

ObjectSpace.each_object(meta).to_a
=> [""]

_.first.object_id
=> 69092310

s.object_id
=> 69092310

Robert D. wrote in post #989182:

On Fri, Mar 25, 2011 at 1:23 PM, Joey Z. [email protected] wrote:

x.rb:3:in singletonclass': undefined local variable or methodstr’ for
#<Class:#String:0x1625bf8> (NameError)

How can I get the value of str(“ABC”) within the class << str;…;end

your problem is that class << x…end is not a closure

x= 42
class << whatever # I disassociate x and whatever for the general case
x # No Method Error as we are not in a closure here
end

But there is a workaround, an idiom you will find quite often in Ruby
metaprogramming

x=42
class << whatever; self end.module_eval do
p x # Works like charm as this is a closure
end

That seems like a ridiculous construct to me(in addition using the
name class_eval() would make more sense than using the name
module_eval()). You are creating a block for module_eval() in order to
print the local variable x. Well guess what? You don’t need a block to
print x:

x = 42

class << whatever
self
end

puts x

Also, you should know that in ruby the keyword ‘class’ starts a new
scope.

Joey Z. wrote in post #989179:

Here is a sample code:

str = “ABC”
class << str
p self
end

What I get is somthing like “#<Class:#String:0x15d4bb0>”.

If “p str”, there’s an error message:

x.rb:3:in singletonclass': undefined local variable or methodstr’ for
#<Class:#String:0x1625bf8> (NameError)

How can I get the value of str(“ABC”) within the class << str;…;end
block?

By creating a method that does just that:

str = “ABC”

class << str
def show
puts self
end
end

str.show

–output:–
ABC

Because str calls the show() method, inside show() self is equal to str.

You have to realize that when you write this:

str = “ABC”

class << str
p self
end

it’s is the same as doing this:

class MyClass
p self
end

obj = MyClass.new

p obj

–output:–
MyClass
#MyClass:0x401bfbf8

…and wondering why ‘p self’ and ‘p obj’ don’t produce the same
results. Inside a class, but outside of any method definitions, self is
equal to the class–that’s why ‘p self’ gives you the class name. On
the other hand, obj is an instance of the class, which is not the same
as the class itself. Therefore, the output of ‘p obj’ is different.

When you do this:

class << str


end

you have opened up a class–what’s called the ‘eigenclass’ of str.
Therefore, everywhere inside the class definition, but outside any
method definitions self is equal to the class–not str.

On Sat, Mar 26, 2011 at 12:31 AM, 7stud – [email protected]
wrote:

Robert D. wrote in post #989182:

What bothers us, is this

x=42
class << self
p x # x is not seen here
end

Although you call my code ridiculous, I agree with you, I think that
class << self should be a closure too, and optimized away if not used as
such.
For now one cannot do better
Cheers
Robert

And thanks for introducing me to ObjectSpace:

irb(main):001:0> foo = “FOO”
=> “FOO”
irb(main):002:0> class << foo
irb(main):003:1> p ObjectSpace.each_object(self).first
irb(main):004:1> end
“FOO”
=> “FOO”

I love learning something new.

Aaron out.

On Sat, Mar 26, 2011 at 4:44 AM, Robert D. [email protected]
wrote:

Cheers
Robert

The fact that class and module definitions are NOT closures is
preferable in my opinion.

irb(main):001:0> foo = “FOO”
=> “FOO”
irb(main):002:0> class MyClass
irb(main):003:1> p foo
irb(main):004:1> end
NameError: undefined local variable or method foo' for MyClass:Class from (irb):3:inclass:MyClass
from (irb):2
from /usr/local/bin/irb:12:in <main>' irb(main):005:0> module MyModule irb(main):006:1> p foo irb(main):007:1> end NameError: undefined local variable or methodfoo’ for MyModule:Module
from (irb):6:in <module:MyModule>' from (irb):5 from /usr/local/bin/irb:12:in

That just seems right.

Aaron out.

On Sat, Mar 26, 2011 at 1:15 PM, Aaron D. Gifford [email protected]
wrote:

On Sat, Mar 26, 2011 at 4:44 AM, Robert D. [email protected] wrote:

That just seems right.

I do not really have a problem with this. However I feel that it is
really not for the language to decide if I want to do this or not. The
more restrictive way does not give me the opportunity to use closures
easily in my classes while it would still allow not to use them. BTW
I am quite convinced that this
is not a design choice, but I am prepared to stand corrected, I rather
think that it is quite a bit of work
to implement this without performance hits and as I do not really
recall [1] any demand of this I am
not surprised that it is not implemented.

[1] IIRC Zed S. asked once why the heck
def … end
could (i) not be a closure and (ii) return the unbound method object.

I would like this very much, but I will not get it, I guess.

Cheers
Robert

On Mon, Mar 28, 2011 at 10:55 AM, Brian C. [email protected]
wrote:

Robert D. wrote in post #989410:

I think it is a design choice, because of the local variable/method
ambiguity.

If “class” and “def” did not start a new scope, then a bareword like “x”
might be a local variable within a closure. It would be extremely
difficult to tell; you’d have to read the entire program source code
back to the beginning of the file (assuming that ‘load’ and ‘require’
started a new scope, otherwise it would be completely impossible).
That is a very good point, I have used closure based programming, and
I have suffered from this.
I however think that I could have done much better than I did. I
missed some opportunities to refactor and introduce more abstraction.
From this experience I conclude that this would be a “feature” to use
with care and that care does not come as natural at first…

Now if you have long modules you will run into the same kind of
problem too. I do not think that Ruby can have a save barrier against
that.

However the parser could restrict closing over one level which could
be overcome with
constructs like this

x=42
class A
x=x
def a; x end …

However I get lost, what really could be a closure, I feel, is
class << x; … end
as we are often in metaprogramming context here.

Cheers
Robert

Robert D. wrote in post #989410:

On Sat, Mar 26, 2011 at 1:15 PM, Aaron D. Gifford [email protected]
wrote:

On Sat, Mar 26, 2011 at 4:44 AM, Robert D. [email protected] wrote:

That just seems right.

I do not really have a problem with this. However I feel that it is
really not for the language to decide if I want to do this or not. The
more restrictive way does not give me the opportunity to use closures
easily in my classes while it would still allow not to use them. BTW
I am quite convinced that this
is not a design choice

I think it is a design choice, because of the local variable/method
ambiguity.

If “class” and “def” did not start a new scope, then a bareword like “x”
might be a local variable within a closure. It would be extremely
difficult to tell; you’d have to read the entire program source code
back to the beginning of the file (assuming that ‘load’ and ‘require’
started a new scope, otherwise it would be completely impossible).

With the current rules, given some code like

… lots of previous stuff
def foo
x
end

you can tell by inspection of method foo alone that x must be a method
call within foo; it’s definitely not a local variable.

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs