On Wed, Jan 22, 2003 at 02:59:44PM +0900, ahoward wrote:
> On 22 Jan 2003, Phil Tomson wrote:
> 
> > That's certianly one way to do it...  I guess I'm looking at Evolvable as
> > more of a namespace than a class that defines an object, though.
> 
> a singleton is really nothing more than an encapsulation of some data and some
> methods - just like a namespace - but i understand your objection
> 
> > And if I leave it as a module it could be mixed into a class later (though
> > that's not how I'm using it now) and all of the 'module instance variables'
> > would also end up in the class it was mixed into....
> 
> i don't think it works that way :
> 
>   module M
>     attr_accessor :x
>     @x = 42
Doesn't refer to the same thing!
 The former will be an iv. of objects extended with M _or_
instanciated from classes that include M.
 The later is a module instance variable, ie, an instance variable
associated to the 'M' object (that of class Module).
>   end
> 
>   class Foo; include M; end
> 
>   p Foo.new.x  # >> nil

Because it's not the same @x!
However
  a = Foo.new
  a.x = 1
  a.x		# 1

> the instance variable STAY in M, that's what i was referring to when i said i
> was unsure of the semantics.

Module instance variables just mimic _class_ instance variables (or the
other way around).

irb(main):001:0> module M
irb(main):002:1>  class << self; attr_accessor :x; end
irb(main):003:1> end
nil
irb(main):004:0> M.x = 1
1
irb(main):005:0> M.x
1
irb(main):006:0> module M2
irb(main):007:1>  @iv = 'ME'
irb(main):008:1>  def M2.iv
irb(main):009:2>    @iv
irb(main):010:2>  end
irb(main):011:1> end
nil
irb(main):012:0> M2.iv
"ME"

Note that module instance variables are bound to the module object;
irb(main):041:0> M.instance_variables
["@x"]

their accessors are defined on singleton class level.

The following won't work:

irb(main):013:0> class Foo; include M; end
Foo
irb(main):014:0> Foo.x
NameError: undefined method `x' for Foo:Class
        from (irb):14
irb(main):015:0> Foo.new.x
NameError: undefined method `x' for #<Foo:0x4026360c>
        from (irb):15

Notice that
irb(main):030:0> singleton_class = class << M; self; end
Module
irb(main):031:0> singleton_class.instance_methods.sort
["x", "x="]

But it's impossible to extend objects with the singleton:
irb(main):032:0> Foo.extend singleton_class
TypeError: wrong argument type Class (expected Module)
        from (irb):32:in `extend'
        from (irb):32

The only ways to access module instance variables are through the
accessors and instance_eval, AFAIK.

-- 
 _           _                             
| |__   __ _| |_ ___ _ __ ___   __ _ _ __  
| '_ \ / _` | __/ __| '_ ` _ \ / _` | '_ \ 
| |_) | (_| | |_\__ \ | | | | | (_| | | | |
|_.__/ \__,_|\__|___/_| |_| |_|\__,_|_| |_|
	Running Debian GNU/Linux Sid (unstable)
batsman dot geo at yahoo dot com

We are MicroSoft.  You will be assimilated.  Resistance is futile.
	-- Attributed to B.G., Gill Bates