Simple Question About Deleting Instances

zdennis wrote:

I had to think about half a second, and then type for about 8 seconds.
Just copy and paste the code and put it in a file that you
require on your projects, and you won't have to think. I will think for
you. Matz is busy solving bigger problems and conquering
better obstacles. So he doesn't have to think about this, I will put my
brain to work for him.

  class Class
    def attr_class_accessor arg
      instance_eval "class << self ; attr_accessor :#{arg} ; end"
    end

    def attr_class_reader arg
      instance_eval "class << self ; attr_reader :#{arg} ; end"
    end

    def attr_class_writer arg
      instance_eval "class << self ; attr_writer :#{arg} ; end"
    end
  end

If you feel this stronlgy about your desire to simplify this, perhaps
you should submit it as an RCR, http://www.rcrchive.net. I
am not saying I think your idea to simplify this into a builtin part of
ruby is a bad thing, but I think that you should not
abolish your ability to think. Ruby gives you power, use it. And if you
think it can be made better, submit a patch or submit an RCR.

Matz gives you the power to influence the langauge, I challenge you to
do so.

It's not so much that I feel strongly as much as that it perplexes me. I
guess I just wanted to make sure my meds haven't been replaced with
crazy pills.

I thought of this, too: isn't it odd that you can define class variables
in a definition of how instances of a class should work, but you can't
define their accessors? It seems inconsistent. If it's agreed that this
is inconsistent, I'll post something to the site you mentioned, but if
it's that way for a reason, I'll just take your much appreciated advice,
learn that much more, and be that much less of a newbie.

···

--
Posted via http://www.ruby-forum.com/\.

zdennis wrote:

[...]

It's not so much that I feel strongly as much as that it perplexes me.
I guess I just wanted to make sure my meds haven't been replaced with
crazy pills.

I thought of this, too: isn't it odd that you can define class
variables in a definition of how instances of a class should work, but
you can't define their accessors? It seems inconsistent. If it's
agreed that this is inconsistent, I'll post something to the site you
mentioned, but if it's that way for a reason, I'll just take your much
appreciated advice, learn that much more, and be that much less of a
newbie.

I'm not sure you're clear on the concept (I don't mean that meanly).

Consider:

  class Foo
    @bar = 5 # the instance variable @bar of <Foo:class> (1)
    @@bar = 5 # the class variable @bar of <Foo:class> (2)

    def initialize
      @bar = 5 # the instance variable @bar of a Foo instance. (3)
    end
  end

When you do:

  class Foo
    class << self
      attr_accessor :bar
    end
  end

You are accessing (1). (2) is not affected.

I addressed some of the reasons *why* you wouldn't simply do:

  attr_accessor :@var

in my article on Symbols in January (on the O'Reilly Ruby blog), but
remember that attr_accessor defines methods. There's no difference
between the types of code here. In fact, if you run "ruby -w" on this
code, you'll get warnings about method redefinitions for the latter two.

  class Foo
    attr_accessor :bar

    def bar; @bar; end
    def bar=(x); @bar = x; end
  end

Jumping back to the Pickaxe:

  class Song
    attr_accessor :duration # in seconds

    def minutes=(x); @duration = (x * 60).to_i; end
    def minutes; @duration / 60; end
  end

  s = Song.new
  s.duration = 60
  s.minutes # => 1
  s.minutes = 2.3
  s.duration # => 138

For documentation purposes, I'll sometimes do the following:

  class Song
    # The duration of the song in seconds.
    attr_accessor :seconds
    # The duration of the song in minutes.
    attr_accessor :minutes
    remove_method :minutes, :minutes=
    def minutes=(m) # :nodoc:
      @seconds = (x * 60).to_i
    end
    def minutes # :nodoc:
      @duration / 60
    end
  end

So using attr_accessor doesn't declare a variable; it declares a pair of
methods that access and may instantiate a variable, but doesn't have to.
And *that* is why doing "attr_accessor :@var" really wouldn't be
appropriate.

-austin

···

On 4/7/06, Nathan Olberding <nathan.olberding@gmail.com> wrote:
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Austin Ziegler wrote:

So using attr_accessor doesn't declare a variable; it declares a pair of
methods that access and may instantiate a variable, but doesn't have to.
And *that* is why doing "attr_accessor :@var" really wouldn't be
appropriate.

I guess to put my question simply, why is there a single context in
which I can define class variables but not class methods (accessors for
these variables)? Shouldn't the two be handled in the same context /
scope / block / area-of-code?

···

--
Posted via http://www.ruby-forum.com/\.

Austin Ziegler wrote:

So using attr_accessor doesn't declare a variable; it declares a pair
of methods that access and may instantiate a variable, but doesn't
have to. And *that* is why doing "attr_accessor :@var" really
wouldn't be appropriate.

I guess to put my question simply, why is there a single context in
which I can define class variables but not class methods (accessors
for these variables)? Shouldn't the two be handled in the same context
/ scope / block / area-of-code?

No. To clarify my statement:

  #attr_accessor creates a pair of instance methods that access and
  may instantiate an instance variable, but don't have to.

Instance variables are always bound to a particular value of self. (I'm
not *quite* sure where class variables reside.)

  >> class Foo
  >> p "#{self.inspect} (#{self.object_id})"
  >> class << self
  >> p "#{self.inspect} (#{self.object_id})"
  >> def myself
  >> p "#{self.inspect} (#{self.object_id})"
  >> end
  >> end
  >> myself
  >> def myself
  >> p "#{self.inspect} (#{self.object_id})"
  >> end
  >> end
  "Foo (23584680)"
  "#<Class:Foo> (23584668)"
  "Foo (23584680)"
  => nil
  >> Foo.new.myself
  "#<Foo:0x2cfa7c8> (23581668)"
  => nil
  >>

So, within the scope of "class Foo", self is a particular object (known
as Foo, oddly enough ;). Within the "class << self" inside of "class
Foo", self is a wholy different object. Within the instance method
declared in "class << self", self is once again the Foo object.

Calling "myself" from the scope of "class Foo" demonstrates this. I
could call Foo.myself can get the same result. What that shows is that
if I use @var inside of the scope of "class Foo", I'm *actually* using
an instance variable inside of that object (of type Class).

Where you seem to be having problem is that unlike other languages,
a simple declaration in Ruby isn't. Declaration is *execution*. There is
no "compile" stage followed by a "run" stage. The two happen together
(as demonstrated above).

"class Foo", "class << self", and "def myself" all change scope and the
meaning of "self" in that scope.

Does that help?

-austin

···

On 4/7/06, Nathan Olberding <nathan.olberding@gmail.com> wrote:
--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Austin Ziegler wrote:

No. To clarify my statement:

  #attr_accessor creates a pair of instance methods that access and
  may instantiate an instance variable, but don't have to.

Instance variables are always bound to a particular value of self. (I'm
not *quite* sure where class variables reside.)

...

"class Foo", "class << self", and "def myself" all change scope and the
meaning of "self" in that scope.

Way, way over my head, but that probably has something to do with the
two-year-old demanding that I stop reading and start wrestling with him.
I'll sleep on this one. Thanks! I think I might have a shot at
understanding this one in the morning.

···

--
Posted via http://www.ruby-forum.com/\.

Nathan O. wrote:

Austin Ziegler wrote:

No. To clarify my statement:

  #attr_accessor creates a pair of instance methods that access and
  may instantiate an instance variable, but don't have to.

Instance variables are always bound to a particular value of self. (I'm
not *quite* sure where class variables reside.)

...

"class Foo", "class << self", and "def myself" all change scope and the
meaning of "self" in that scope.

Way, way over my head, but that probably has something to do with the
two-year-old demanding that I stop reading and start wrestling with him.
I'll sleep on this one. Thanks! I think I might have a shot at
understanding this one in the morning.

As traditional as they are, for me the Foo/bar style examples can be
confusing because they give no context.

The Pickaxe book gives a good example of the difference between instance
variables and class variables and how they can be useful. Perhaps this
is stuff you already know, but it can be helpful to cover it again.

In the Pickaxe example (paraphrasing the code), they're making a Jukebox
application which plays songs and records the total number of plays of
each song, as well as the total number of songs played by the jukebox.

class Song
  attr_accessor :name, :artist, :duration, :plays

  @@total_plays = 0 # class variable, the total number of all songs
played by the jukebox

  def initialize(name, duration)
    self.name = name # using the accessor methods
    self.artist = artist # using the accessor methods
    self.duration = duration # using the accessor methods
    plays = 0 # using the accessor methods
  end

  def play
    @@total_plays += 1 # increase the total count
    self.plays += 1 # increase the count for this song
    # play the song
  end
end

So if you do this:

so_what = Song.new("So What", "Miles Davis", 9.24)

so_what.play
so_what.play
Song.total_plays #=> 2
so_what.plays #=> 2

penny_lane = Song.new("Penny Lane", "The Beatles", 3.45)

penny_lane.play
penny_lane.play

Song.total_plays #=> 4
penny_lane.plays #=> 2

So the "@@total_plays" variable stores a value unique to the class of
Song, regardless of instances. And the instance variables store values
unique to each instance. The class variable can be "declared" or used
in the body of the class definition, but the instance variable should be
used in the body of a method.

I'm sure you know most of this, but hopefully it helps a bit.

Jeff Coleman

···

--
Posted via http://www.ruby-forum.com/\.

Fair enough. However, let me point out that you showed something
*different* than I showed. I deliberately didn't get into class
variables (@@var) because the point I was making was solely about the
change of scope, and @@var is a little funny with scope (I personally
think it's broken, and I simply don't use them any more).

In many ways, the Pickaxe Song/Jukebox example is bad anyway; the
*Jukebox* should be keeping track of how many songs it has played, not
the Song class, which may be used by other Jukebox instances, and for
billing purposes, you don't want those song counts commingled. :slight_smile:

In your example, you also didn't give a definition for
Song::total_plays.

If, however, we were to accept the Pickaxe premise as valid, here's what
I would do:

  class Song
    attr_accessor :name
    attr_accessor :artist
    attr_accessor :duration
    attr_reader :plays

    # Class instance variable
    @total_plays = 0

    class << self
      attr_reader :total_plays
    end

    # This could be in the class << self as def add_play...
    def self.add_play
      @total_plays += 1
    end

    def initialize(name, artist, duration)
      self.name = name
      self.artist = artist
      self.duration = duration
      @plays = 0
    end

    def play
      self.class.add_play
      @plays += 1
      # play the song
    end
  end

@total_plays in the "class Song" scope belongs to the self that *is*
"class Song". This is the same scope within "def self.add_play" or in
the method defined by "class << self; attr_reader :total_plays; end".

-austin

···

On 4/8/06, Jeff Coleman <progressions@gmail.com> wrote:

Nathan O. wrote:

Austin Ziegler wrote:

No. To clarify my statement:

  #attr_accessor creates a pair of instance methods that access and
  may instantiate an instance variable, but don't have to.

Instance variables are always bound to a particular value of self.
(I'm not *quite* sure where class variables reside.)
...
"class Foo", "class << self", and "def myself" all change scope and
the meaning of "self" in that scope.

Way, way over my head, but that probably has something to do with the
two-year-old demanding that I stop reading and start wrestling with
him. I'll sleep on this one. Thanks! I think I might have a shot at
understanding this one in the morning.

As traditional as they are, for me the Foo/bar style examples can be
confusing because they give no context.

--
Austin Ziegler * halostatue@gmail.com
               * Alternate: austin@halostatue.ca

Austin Ziegler wrote:

.. a bunch of good stuff snipped ..

Thanks for your corrections, Austin, I see your points.

I certainly didn't mean to criticize your examples, I just felt like it
might help to bring the discussion to some concrete examples, as the
original poster seemed to have a confusion about the nature of class
versus instance variables, which IMO might be cleared up before the
higher-level discussion about scoping becomes useful.

Jeff

···

--
Posted via http://www.ruby-forum.com/\.