I am attempting to write a transparent persistence framework and am having a
hard time deciding if something should be a class or it should be a module.
The reason I would like it to be a module is because I am trying to write a
framework where I do not want to interfere with the object model used by
clients of the framework. Ideally they would just include my module and get
my functionality for free thus making persistence even more transparent.
Where I get confused is that this module needs to set some instance variable
state and initialize those variables. I would like it if there was a way for
the state to be set after the the client object has been initialized? If that
is not possible, or possibly not the best way to do it then please let me
know.
Here is some code:
···
Encapsulates the behavior needed to make objects persistent and is the
module
all classes wishing to be persisted should mix this in.
module ROS
module Persistable
def initialize
# I want these variables to be instance vars. @is_persistent = false @timestamp = null
end
Thank you for the quick response Guy! Although I’m not sure how the initialize
method in the Module is called. I see you make a call to super there, but I
was not aware that a super call would call methods in a Module! The behavior
is exactly what was desired though. Must I call super from the class to get
the Modules initialize method called?
module M
def initialize
puts "M"
end
end
class A
def initialize
puts "A"
end
end
class B < A
include M
def initialize
puts "B"
super
end
end
b = B.new
B
M
A#initialize doesn’t get invoked. To ensure this, we must
call #super from M#initialize:
module M
def initialize
puts "M"
super
end
end
b = B.new
B
M
A
Of course, observe the order in which they get invoked, though.
And, requiring #initialize to invoke #super means that mixing
the module in with something like the String class becomes
tricky.
ruby has inserted a proxy class [ROS::Persistence] before A
In A#initialize when you call #super, ruby find the method
ROS::Persistence#initialize
–
Dossy Shiobara mail: dossy@panoptic.com
Panoptic Computer Network web: http://www.panoptic.com/
“He realized the fastest way to change is to laugh at your own
folly – then you can let go and quickly move on.” (p. 70)
i did not realize this either. what happens if you include more then one
module?
It do the same, for example
class A # A ==> Object ==> [Kernel]
include B # A ==> [B] ==> Object ==> [Kernel]
include C # A ==> [C] ==> [B] ==> Object ==> [Kernel]
include B # A ==> [C] ==> [B] ==> Object ==> [Kernel]
# not modified because it has found the proxy class [B]
Now with
module C end
module B
include C
end
class A
include B # A ==> [B] ==> [C] ==> Object ==> [Kernel]
end
Ok, with this nice illustration of how it works, I should definately call
super from the intialize method i have in the module, no?
Signed,
Holden Glova
···
On Sun, 11 Aug 2002 21:50, ts wrote:
i did not realize this either. what happens if you include more then one
module?
It do the same, for example
class A # A ==> Object ==> [Kernel]
include B # A ==> [B] ==> Object ==> [Kernel]
include C # A ==> [C] ==> [B] ==> Object ==> [Kernel]
include B # A ==> [C] ==> [B] ==> Object ==> [Kernel]
# not modified because it has found the proxy class [B]
Now with
module C end
module B
include C
end
class A
include B # A ==> [B] ==> [C] ==> Object ==> [Kernel]
end
Ok, with this nice illustration of how it works, I should definately
call H> super from the intialize method i have in the module, no?
no, with
module B
def initialize
super
end
end
class A
include B
end
A.new
ruby call B#initialize but the #super in B#initialize will search #initialize in Object, then Kernel
I don’t see how that is a bad thing?
with
class A
include B
def initialize
# without super
end
end
ruby call only A#initialize
Guy Decoux
Reason why I suggested adding super in the Module was because if the client
chooses to do something similar with other modules then by my Module not
calling super would mean that the other Module#initialize methods defined in
their modules would not be called - is that correct?
pigeon% ruby
module B
def initialize(a)
p "B"
super
end
end
class A
include B
end
A.new(12)
^D
"B"
-:4:in `initialize': wrong # of arguments(1 for 0) (ArgumentError)
from -:4:in `initialize'
from -:12:in `new'
from -:12
pigeon%
Reason why I suggested adding super in the Module was because if the client
chooses to do something similar with other modules then by my Module not
calling super would mean that the other Module#initialize methods defined in
their modules would not be called - is that correct?