Ok, code below shows better what I am talking about, I understand that
@@var is acting like global variable.
But how to get rid of it when is not needed anymore?
class A
@@var = 'var in A'
def self.item
@@var
end
def self.item=(var)
@@var=var
end
end
class B
@@var = 'var in B'
def self.item
@@var
end
def self.item=(var)
@@var=var
end
end
A.item => "var in A"
B.item => "var in B"
A.item='test'
A.item => "test"
B.item => "var in B"
@@var ='ltl fkr' #here is the funny part
A.item => "ltl fkr"
B.item => "ltl fkr"
A.item='test' #and here is getting even funnier
A.item => "test"
B.item => "test" # i wish it to stay 'ltl fkr'
Ok, code below shows better what I am talking about, I understand that
@@var is acting like global variable.
But how to get rid of it when is not needed anymore?
[...]
A.item => "var in A"
B.item => "var in B"
A.item='test'
A.item => "test"
B.item => "var in B"
@@var ='ltl fkr' #here is the funny part
A.item => "ltl fkr"
B.item => "ltl fkr"
A.item='test' #and here is getting even funnier
A.item => "test"
B.item => "test" # i wish it to stay 'ltl fkr'
You're trying to maintain and alter state on a per-class basis, which
really means on a per-object (class object) basis. Class variables are
not suited to that purpose; they are, as you say, really sort of
vertical globals.
(In fact, I've always thought that $$var would be a better designation
for class variables than @@var, because @@var makes it look like class
variables have some kind of affinity with instance variables, which
they definitely don't.)
Anyway -- I don't know of any way to undefine a class variable. I'd
recommend using instance variables if you need per-class state.
Ok, code below shows better what I am talking about, I understand that
@@var is acting like global variable.
But how to get rid of it when is not needed anymore?
class A
@@var = 'var in A'
class <<self
def item ; @@var ; end
def item= var ; @@var = var ; end
end
end
class B
@@var = 'var in B'
class <<self
def item ; @@var ; end
def item= var ; @@var = var ; end
end
end
A.item #=> "var in A"
B.item #=> "var in B"
A.item='test'
A.item #=> "test"
B.item #=> "var in B"
@@var ='ltl fkr' #here is the funny part
A.item #=> "ltl fkr"
B.item #=> "ltl fkr"
A.item='test' #and here is getting even funnier
A.item #=> "test"
B.item #=> "test" # i wish it to stay 'ltl fkr'
I cannot reproduce it here with Ruby 1.8.6. Are you using 1.9?
I guess A's and B's @@var gets superseded by Object's @@var.
Try to check these calls:
Object.class_variables
class Object ; remove_class_variable "@@var" ; end
Object.instance_eval { remove_class_variable "@@var" }
A.item => "test"
B.item => "test" # i wish it to stay 'ltl fkr'
The first time through I didn't even quite pick up on what you were
illustrating. (I think my brain interpolated class B < A because
that's what class variable questions usually involve
This looks like a bug in 1.9 to me. I can't come up with any reason
why it should act like that -- the outer-scope part affecting the
class variables of A, those of A affecting those of B (without
inheritance), etc.
Even if remove_class_variable can help you, I would strongly recommend
not getting embroiled in that. I'd still advocate rewriting it to
avoid class variables.
Ok, code below shows better what I am talking about, I understand that
@@var is acting like global variable.
But how to get rid of it when is not needed anymore?
You're trying to maintain and alter state on a per-class basis, which
really means on a per-object (class object) basis. Class variables are
not suited to that purpose; they are, as you say, really sort of
vertical globals.
(In fact, I've always thought that $$var would be a better designation
for class variables than @@var, because @@var makes it look like class
variables have some kind of affinity with instance variables, which
they definitely don't.)
The only commonality I can think of off the top of my head is the fact that you can use them from within instances much the same way as instance variables.
Anyway -- I don't know of any way to undefine a class variable. I'd
recommend using instance variables if you need per-class state.
My 0.02 EUR: the best way to get rid of class variables is to not use them in the first place.
Ok, code below shows better what I am talking about, I understand that
@@var is acting like global variable.
But how to get rid of it when is not needed anymore?
You're trying to maintain and alter state on a per-class basis, which
really means on a per-object (class object) basis. Class variables are
not suited to that purpose; they are, as you say, really sort of
vertical globals.
(In fact, I've always thought that $$var would be a better designation
for class variables than @@var, because @@var makes it look like class
variables have some kind of affinity with instance variables, which
they definitely don't.)
The only commonality I can think of off the top of my head is the fact that you can use them from within instances much the same way as instance variables.
But you're always within an instance of something. You can access
global variables there too
This is also why I don't like the "cattr_*" idiom (cattr_reader and so
on), or at least its naming. "Attribute" suggests an attribute of a
particular object. Class variables don't represent per-object state,
so they're not suited to "attribute" implementation.
Anyway -- I don't know of any way to undefine a class variable. I'd
recommend using instance variables if you need per-class state.
My 0.02 EUR: the best way to get rid of class variables is to not use them in the first place.
class Object ; remove_class_variable "@@var" ; end
I forgot all about that method. I guess I'm rusty on class variables,
from lack of use
I don't use them either. Sometimes I wonder about that because
a "@@var" is much shorter than a "MyClass.var". It seems to be
more disturbing you than simplifying your code. I did some weird
things like these:
class C ; end
C.class.instance_eval "@@x = 'X'"
class <<C ; @@y = "Y" ; end
I gave up trying to understand it.
The easiest thing is when accessors look the same in classes and
in instances:
class MyClass
attr_accessor :iv # @iv in MyClass.new
class <<self
attr_accessor :cv # @cv in MyClass
end @cv = "initial"
end
Bertram
···
Am Samstag, 04. Jul 2009, 23:40:32 +0900 schrieb David A. Black:
Am Samstag, 04. Jul 2009, 23:40:32 +0900 schrieb David A. Black:
On Sat, 4 Jul 2009, Bertram Scharpf wrote:
class Object ; remove_class_variable "@@var" ; end
I forgot all about that method. I guess I'm rusty on class variables,
from lack of use
I don't use them either. Sometimes I wonder about that because
a "@@var" is much shorter than a "MyClass.var". It seems to be
more disturbing you than simplifying your code. I did some weird
things like these:
class C ; end
C.class.instance_eval "@@x = 'X'"
class <<C ; @@y = "Y" ; end
I gave up trying to understand it.
The easiest thing is when accessors look the same in classes and
in instances:
class MyClass
attr_accessor :iv # @iv in MyClass.new
class <<self
attr_accessor :cv # @cv in MyClass
end @cv = "initial"
end
Yes; I definitely think it's a case where the "classes are objects
too" thing makes it fall into place.
Thank you guys, all your tips were very useful.
It was just dummy example(inspired from Pickaxe Book) that made me
thinking, remove_class_variable method was exactly what I looked for
[ I really cant believe I missed it :)).
and $$class_variable explanation works very well for my brain.
Big Cheers from Bart
···
On Jul 5, 10:07 am, "David A. Black" <dbl...@rubypal.com> wrote:
Hi --
On Sun, 5 Jul 2009, Bertram Scharpf wrote:
> Hi,
> Am Samstag, 04. Jul 2009, 23:40:32 +0900 schrieb David A. Black:
>> On Sat, 4 Jul 2009, Bertram Scharpf wrote:
>>> class Object ; remove_class_variable "@@var" ; end
>> I forgot all about that method. I guess I'm rusty on class variables,
>> from lack of use
> I don't use them either. Sometimes I wonder about that because
> a "@@var" is much shorter than a "MyClass.var". It seems to be
> more disturbing you than simplifying your code. I did some weird
> things like these:
> class C ; end
> C.class.instance_eval "@@x = 'X'"
> class <<C ; @@y = "Y" ; end
> I gave up trying to understand it.
> The easiest thing is when accessors look the same in classes and
> in instances:
> class MyClass
> attr_accessor :iv # @iv in MyClass.new
> class <<self
> attr_accessor :cv # @cv in MyClass
> end
> @cv = "initial"
> end
Yes; I definitely think it's a case where the "classes are objects
too" thing makes it fall into place.