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 method
str’ 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 method
str’ 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
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 method
str’ 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 method
str’ 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:in
class: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 method
foo’ 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.