Accessors for module instance vars

I’ve got a module that that has several classes defined within it. These
classes need to access some instance variables defined at the module
level.

For example:

module Evolvable
PC = 0.2
PM = 0.01
def Evolvable.init(pc=Evolvable::PC,pm=Evolvable::PM,crossovertype=:uniform)
@pc = pc
@pm = pm
@crossoverType = crossovertype
end

def Evolvable.get_pm
@pm
end

def Evolvable.get_pc
@pc
end

def Evolvable.get_crossoverType
@crossoverType
end
#and set methods too

class Population
def initialize

end

def do_crossover(pc=Evolvable.get_pc, type=Evolvable.get_crossoverType)
  ...
end

def do_mutate(pm=Evolvable.get_pm)
  ...
end

end
end

#and to use it:

Evolvable.init(0.2, 0.01, :two_point)
#…later…
Evolvable.set_crossoverType :uniform
#do more stuff
#end

Now this works ok, but I’m wondering if there’s a way to create the
accessor methods for the Evolvable module automatically like with
attr_accessor and attr_reader. The problem with attr_accessor is that it
creates an instance method, not a module method - is there a way to
automatically create a module method?

Phil

···


"Or perhaps the truth is less interesting than the facts?"
Amy Weiss (accusing theregister.co.uk of engaging in ‘tabloid journalism’)
Senior VP, Communications
Recording Industry Association of America

Phil Tomson wrote:

Now this works ok, but I’m wondering if there’s a way to create the
accessor methods for the Evolvable module automatically like with
attr_accessor and attr_reader. The problem with attr_accessor is that it
creates an instance method, not a module method - is there a way to
automatically create a module method?

Phil

irb(main):001:0> module M
irb(main):002:1> class << self; attr_accessor :foo; end
irb(main):003:1> end
nil
irb(main):004:0> M.foo
nil
irb(main):005:0> M.foo = 4
4
irb(main):006:0> M.foo
4

I’ve got a module that that has several classes defined within it. These
classes need to access some instance variables defined at the module
level.

For example:

module Evolvable
PC = 0.2
PM = 0.01

end

Now this works ok, but I’m wondering if there’s a way to create the
accessor methods for the Evolvable module automatically like with
attr_accessor and attr_reader. The problem with attr_accessor is that it
creates an instance method, not a module method - is there a way to
automatically create a module method?

i’m unsure of the semantics of instance variables in a module (something you
cannot declare an instance of) but assuming you need both the module defaults
AND ‘instance variable’ in your module (perhaps because you will want to tweak
these ‘instance variables’ later and yet have sensible defaults) why not
simply :

class Evolvable
require ‘singleton’
include Singleton

private

PC = 0.2

def initialize
  @pc = PC
end

attr_writer :pc

public

attr_reader :pc

end

e = Evolvable.instance
puts e.pc # >> 0.2

perhaps PC should be @@pc or something, but you get the picture :

by putting the vars in a class you can use attr_*, but making the class a Singleton you ensure only one copy of @pc will ever exist.

-a

···

On 21 Jan 2003, Phil Tomson wrote:

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

In article 3E2DA7AD.6040604@path.berkeley.edu,

Phil Tomson wrote:

Now this works ok, but I’m wondering if there’s a way to create the
accessor methods for the Evolvable module automatically like with
attr_accessor and attr_reader. The problem with attr_accessor is that it
creates an instance method, not a module method - is there a way to
automatically create a module method?

Phil

irb(main):001:0> module M
irb(main):002:1> class << self; attr_accessor :foo; end
irb(main):003:1> end
nil
irb(main):004:0> M.foo
nil
irb(main):005:0> M.foo = 4
4
irb(main):006:0> M.foo
4

Great! I wasn’t sure if that would work.

Actually, about an hour after I posted I had a different idea which means
that I cant’ use attr_accessor anyway.
I decided that if the modules hadn’t been ‘initialized’ that the ‘get’
methods should do some sort of default initialization:

module Evolvable
XOVER_DEFAULT = :uniform

#…

def Evolvable.set_crossoverType(type=XOVER_DEFAULT)
@crossoverType = type
end

def Evolvable.get_crossoverType
if not defined? @crossoverType
#default in case it hasn’t been set:
@crossoverType = XOVER_DEFAULT
end
@crossoverType
end

end

…so I can’t use attr_accessor anyway if I want this kind of
functionality.

Phil

···

Joel VanderWerf vjoel@PATH.Berkeley.EDU wrote:

“Or perhaps the truth is less interesting than the facts?”
Amy Weiss (accusing theregister.co.uk of engaging in ‘tabloid journalism’)
Senior VP, Communications
Recording Industry Association of America

In article Pine.LNX.4.33.0301212020500.6373-100000@eli.fsl.noaa.gov,

I’ve got a module that that has several classes defined within it. These
classes need to access some instance variables defined at the module
level.

For example:

module Evolvable
PC = 0.2
PM = 0.01

end

Now this works ok, but I’m wondering if there’s a way to create the
accessor methods for the Evolvable module automatically like with
attr_accessor and attr_reader. The problem with attr_accessor is that it
creates an instance method, not a module method - is there a way to
automatically create a module method?

i’m unsure of the semantics of instance variables in a module (something you
cannot declare an instance of)

Actually they seem to be allowed (perhaps ‘module instance variable’ isn’t
the right term, though) but they must be set and accessed through module
methods (def ModuleName.methodname…).

but assuming you need both the module defaults
AND ‘instance variable’ in your module (perhaps because you will want to tweak
these ‘instance variables’ later and yet have sensible defaults) why not
simply :

class Evolvable
require ‘singleton’
include Singleton

private

PC = 0.2

def initialize
@pc = PC
end

attr_writer :pc

public

attr_reader :pc
end

e = Evolvable.instance
puts e.pc # >> 0.2

perhaps PC should be @@pc or something, but you get the picture :

by putting the vars in a class you can use attr_*, but making the class
a Singleton you ensure only one copy of @pc will ever exist.

-a

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. 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… though there might be some
issues with mixing in the module methods.

Phil

···

ahoward ahoward@fsl.noaa.gov wrote:

On 21 Jan 2003, Phil Tomson wrote:

“Or perhaps the truth is less interesting than the facts?”
Amy Weiss (accusing theregister.co.uk of engaging in ‘tabloid journalism’)
Senior VP, Communications
Recording Industry Association of America

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
end

class Foo; include M; end

p Foo.new.x # >> nil

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

-a

···

On 22 Jan 2003, Phil Tomson wrote:

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

In article Pine.LNX.4.33.0301220531480.26588-100000@eli.fsl.noaa.gov,

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
end

class Foo; include M; end

p Foo.new.x # >> nil

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

this works:

module M
def x
if not defined? @x
@x = 0
end
@x
end

def x=(x)
@x=x
end
end

class Foo; include M; end

Foo.new.x #-> 0

However, those are instance methods (x and x=) defined in module M and
since M can’t be instantiated they are only callable after M is mixed into
a class and an instance of that class is created.

I wonder if there is a way to mixin module methods so that they become
instance methods of a class?

module M
def M.x
if not defined? @x
@x=0
end
@x
end
end

class MyM
include_module_methods_of M #somehow
end

MyM.new.x #-> 0

Anyone know of a way to do this? (I have no pressing need for this, just
curious)

Phil

···

ahoward ahoward@fsl.noaa.gov wrote:

On 22 Jan 2003, Phil Tomson wrote:


“Or perhaps the truth is less interesting than the facts?”
Amy Weiss (accusing theregister.co.uk of engaging in ‘tabloid journalism’)
Senior VP, Communications
Recording Industry Association of America

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.

···

On Wed, Jan 22, 2003 at 02:59:44PM +0900, ahoward wrote:

On 22 Jan 2003, Phil Tomson wrote:


_ _

__ __ | | ___ _ __ ___ __ _ _ __
'_ \ / | __/ __| '_ _ \ / ` | ’ \
) | (| | |
__ \ | | | | | (| | | | |
.__/ _,
|_|/| || ||_,|| |_|
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

In article Pine.LNX.4.33.0301220531480.26588-100000@eli.fsl.noaa.gov,

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
end

class Foo; include M; end

p Foo.new.x # >> nil

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

See my other post.

this works:

module M
def x
if not defined? @x
@x = 0
end
@x
end

def x=(x)
@x=x
end
end

class Foo; include M; end

Foo.new.x #-> 0

But you’re not using the module instance variable of M!

However, those are instance methods (x and x=) defined in module M and
since M can’t be instantiated they are only callable after M is mixed into
a class and an instance of that class is created.

I wonder if there is a way to mixin module methods so that they become
instance methods of a class?

module M
def M.x
if not defined? @x
@x=0
end
@x
end
end

This one is.

class MyM
include_module_methods_of M #somehow
end

MyM.new.x #-> 0

If that worked, it’d mean that you’re extending one object with the
singleton class of M, which is AFAIK impossible since it’s a virtual
class. You cannot ‘transfer’ singleton methods.

module M
def M.x
@x
end
def M.x= a
@x = a
end
end
=> nil
M.x
=> nil
M.x = 1
=> 1
M.x
=> 1
singleton_class = class << M; self; end
=> Module
class Foo < singleton_class
end
TypeError: can’t make subclass of virtual class
from (irb):13
singleton_class.instance_methods
=> [“x”, “x=”]
Foo.extend singleton_class
TypeError: wrong argument type Class (expected Module)
from (irb):24:in extend' from (irb):24 M.singleton_methods => ["x", "x="] Foo.extend M => Foo Foo.x NameError: undefined method x’ for Foo:Class
from (irb):35
class Foo
include M
end
=> Foo
Foo.x
NameError: undefined method x' for Foo:Class from (irb):40 Foo.new.x NameError: undefined method x’ for #Foo:0x4022e908
from (irb):41

Anyone know of a way to do this? (I have no pressing need for this, just
curious)

Just wait for Guy Decoux’ post to correct me and find a way or confirm
it cannot be done :wink:

···

On Wed, Jan 22, 2003 at 06:00:03PM +0900, Phil Tomson wrote:

ahoward ahoward@fsl.noaa.gov wrote:

On 22 Jan 2003, Phil Tomson wrote:


_ _

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

Do you mean to say that I can read mail with vi too? :wink:
Didn’t you know that?
:r /var/spool/mail/jk
– debian-mentors

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

that was my point.

> irb(main):001:0> module M > irb(main):002:1> class < irb(main):003:1> end > nil > irb(main):004:0> M.x = 1 > 1 > irb(main):005:0> M.x > 1

didn’t know you could do that…

> 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 # > from (irb):15

yes. all the more reason this idea :

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

will not work.

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

AFAIK → ???

-a

···

On Wed, 22 Jan 2003, Mauricio Fernández wrote:

====================================

Ara Howard
NOAA Forecast Systems Laboratory
Information and Technology Services
Data Systems Group
R/FST 325 Broadway
Boulder, CO 80305-3328
Email: ahoward@fsl.noaa.gov
Phone: 303-497-7238
Fax: 303-497-7259
====================================

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

that was my point.

This is why we like class instance variables :slight_smile:
The interesting thing about them is that they belong only to that
class, not to subclasses like class variables:

class A
@@var = ‘A::@@var so to speak’
end
=> “A::@@var so to speak”
class B < A
def a
@@var
end
end
=> nil
B.new.a
=> “A::@@var so to speak”
class << A; def x= a; @x = a; end; end
=> nil
class << A; def x; @x; end; end
=> nil
class A
def interesting
self.class.x
end
end
=> nil
a = A.new
=> #<A:0x40266ec4>
A.x= ‘belongs only to A’
=> “belongs only to A”
a.interesting
=> “belongs only to A”
B.new.interesting
=> nil

For one stupid use of this, see below.

> irb(main):001:0> module M > irb(main):002:1> class < irb(main):003:1> end > nil > irb(main):004:0> M.x = 1 > 1 > irb(main):005:0> M.x > 1

didn’t know you could do that…

And that way you can for instance do the following (but take it with a
grain of salt, as I suspect somebody will find some horrible flaw :-P)

batsman@tux-chan:/tmp$ cat b.rb
module CountInstances
def new(*args, &p)
@instances ||= 0
@instances += 1
super *args, &p
end

    def instances
            @instances || 0
    end

end

class A
extend CountInstances
def initialize
puts “Creating instance of #{self.class}”
end
end

class B < A
# can have that functionality by subclassing A or using
#extend CountInstances
end

puts “Made #{A.instances} instances of A.”
puts “Made #{B.instances} instances of B.”
2.times { A.new; B.new }
1.times { B.new }
puts “Made #{A.instances} instances of A.”
puts “Made #{B.instances} instances of B.”
batsman@tux-chan:/tmp$ ruby b.rb
Made 0 instances of A.
Made 0 instances of B.
Creating instance of A
Creating instance of B
Creating instance of A
Creating instance of B
Creating instance of B
Made 2 instances of A.
Made 3 instances of B.

It works because B < A but B.class is not derived from A.class :slight_smile: so
the @iv are not the same one depending on initialization order as for
normal instance vars.

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

AFAIK → ???

AFAIK, IIRC :slight_smile:

···

On Thu, Jan 23, 2003 at 12:20:45AM +0900, ahoward wrote:

On Wed, 22 Jan 2003, Mauricio Fernández wrote:


_ _

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

Remember: While root can do most everything, there are certain
privileges that only a partner can grant.
– Telsa Gwynne

OH no! I didn’t mean to contract this here!
This is really stupid, I was going to write “As Far As I Know” but my
mind changed it to AFAIK as I was about to write it :wink: Acronyms are
viral, really! :slight_smile:

···

On Thu, Jan 23, 2003 at 01:39:03AM +0900, Mauricio Fernández wrote:

AFAIK, IIRC :slight_smile:


_ _

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

Win95 is not a virus; a virus does something.
– unknown source

It works because B < A but B.class is _not_ derived from A.class :slight_smile: so

What do you want to say with this ?

pigeon% cat b.rb
#!/usr/bin/ruby
class A; end
class B < A; end;
p (B < A)
p ((class << B; self; end) < (class << A; self; end))
pigeon%

pigeon% b.rb
true
true
pigeon%

Guy Decoux

I meant that
batsman@tux-chan:/tmp$ cat c.rb
class A; end
class B < A; end;
p (B < A)
p (B.class < A.class)
batsman@tux-chan:/tmp$ ruby c.rb
true
false

as both are of class Class. If there was an automatic relationship
between the classes of the classes, my example wouldn’t work.

It’s always interesting to see that there is indeed a inheritance
relation between singletons…

PS: does this mean that my ‘instance counting’ code is correct?

···

On Thu, Jan 23, 2003 at 01:55:01AM +0900, ts wrote:

It works because B < A but B.class is not derived from A.class :slight_smile: so

What do you want to say with this ?

pigeon% cat b.rb
#!/usr/bin/ruby
class A; end
class B < A; end;
p (B < A)
p ((class << B; self; end) < (class << A; self; end))
pigeon%

pigeon% b.rb
true
true
pigeon%


_ _

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

Look, I’m about to buy me a double barreled sawed off shotgun and show
Linus what I think about backspace and delete not working.
– some anonymous .signature

PS: does this mean that my 'instance counting' code is correct?

yes,

Guy Decoux

I meant that
batsman@tux-chan:/tmp$ cat c.rb
class A; end
class B < A; end;
p (B < A)
p (B.class < A.class)
batsman@tux-chan:/tmp$ ruby c.rb
true
false

as both are of class Class. If there was an automatic relationship
between the classes of the classes, my example wouldn’t work.

class A; end
=> nil
A < (class << A; self; end)
=> false
A > (class << A; self; end)
=> false
A <=> (class << A; self; end)
=> 1

Can anyone tell me what to make of that? I thought that the singleton
of a class inherited from the class. The operation of “super” within
a singleton implies that.

Gavin

···

On Thursday, January 23, 2003, 4:08:49 AM, Mauricio wrote:

class A; def a; “A#A”; end; end
==>nil
class << A; def a; “A.a”; super; end; end
==>nil
A.a
NameError: super: no superclass method a' from (irb):7:in a’
from (irb):8

However
class A; class << self; def a; p “A.a”; end; end; end
==>nil
class B < A; class << self; def a; p “B.a”; super; end; end; end
==>nil
A.a
“A.a”
==>nil
B.a
“B.a”
“A.a”
==>nil

Take a look at the Pickaxe, figure 19.2, p. 244.
The singleton doesn’t inherit from the class; if it did, all instance
methods would become class methods too!

As for the starship operator… it cannot return anything meaningful,
can it? I mean we cannot assume that
A <=> B == 1 => A > B

···

On Thu, Jan 23, 2003 at 01:01:26PM +0900, Gavin Sinclair wrote:

On Thursday, January 23, 2003, 4:08:49 AM, Mauricio wrote:

I meant that
batsman@tux-chan:/tmp$ cat c.rb
class A; end
class B < A; end;
p (B < A)
p (B.class < A.class)
batsman@tux-chan:/tmp$ ruby c.rb
true
false

as both are of class Class. If there was an automatic relationship
between the classes of the classes, my example wouldn’t work.

class A; end
=> nil
A < (class << A; self; end)
=> false
A > (class << A; self; end)
=> false
A <=> (class << A; self; end)
=> 1

Can anyone tell me what to make of that? I thought that the singleton
of a class inherited from the class. The operation of “super” within
a singleton implies that.


_ _

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

Problem solving under Linux has never been the circus that it is under
AIX.
– Pete Ehlke in comp.unix.aix