How to remove/delete/destroy class variable in Ruby 1.9?

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'

Hi --

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.

David

···

On Sat, 4 Jul 2009, dzw! wrote:

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info: http://rubyurl.com/vmzN\)

Hi,

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" }

  (Object.methods - Object.instance_methods).grep /var/
    #=> ["class_variables", "class_variable_defined?"]

  (Object.private_methods - Object.private_instance_methods).grep /var/
    #=> ["remove_class_variable", "class_variable_get", "class_variable_set"]

Bertram

···

Am Samstag, 04. Jul 2009, 16:30:05 +0900 schrieb dzw!:

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

Hi --

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'

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 :slight_smile:

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.

David

···

On Sat, 4 Jul 2009, dzw! wrote:

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info: http://rubyurl.com/vmzN\)

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. :slight_smile:

Kind regards

  robert

···

On 04.07.2009 14:06, David A. Black wrote:

On Sat, 4 Jul 2009, dzw! wrote:

--
remember.guy do |as, often| as.you_can - without end
http://blog.rubybestpractices.com/

Hi --

···

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 :slight_smile:

David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info: http://rubyurl.com/vmzN\)

Hi --

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 :slight_smile:

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. :slight_smile:

I agree.

David

···

On Sat, 4 Jul 2009, Robert Klemme wrote:

On 04.07.2009 14:06, David A. Black wrote:

On Sat, 4 Jul 2009, dzw! wrote:

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info: http://rubyurl.com/vmzN\)

Hi,

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 :slight_smile:

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:

On Sat, 4 Jul 2009, Bertram Scharpf wrote:

--
Bertram Scharpf
Stuttgart, Deutschland/Germany
http://www.bertram-scharpf.de

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 :slight_smile:

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.

David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training: http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info: http://rubyurl.com/vmzN\)

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 :slight_smile:

> 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.

David

--
David A. Black / Ruby Power and Light, LLC
Ruby/Rails consulting & training:http://www.rubypal.com
Now available: The Well-Grounded Rubyist (http://manning.com/black2\)
Training! Intro to Ruby, with Black & Kastner, September 14-17
(More info:http://rubyurl.com/vmzN\)