Initializing instance variables in a module

How about “included” instead of “instantiated”?

Hi,

In message “Re: [OT] Re: initializing instance variables in a module”

|the other day i realized that one could detect class creation using
|
| class Class
| def inherited
| …
| end
| end
|
|but that no such hook existed for class Module. could one be added such as
|
| class Module
| def instantiated
| …
| end
| end
|
|to hook into rb_define_module/rb_define_module_under?

I am not sure what situation that kind of method is useful. But in
any case I don’t feel the word “instantiated” is the right word for
the method. Note that I am not opposing the method itself.

						matz.

On Tue, 23 May 2006, Yukihiro M. wrote:

I am not sure what situation that kind of method is useful.

harp:~ > cat a.rb
class Class
WRAPPER = []
def inherited other
wrapper = WRAPPER.first
wrapper.const_set other.name.split(%r/::/).last, other if wrapper
end
def load file, m
wrapping(m){ ::Kernel.load file, wrap = true }
end
def wrapping m
WRAPPER.push m
yield
ensure
WRAPPER.pop
end
end

m = Module.new

Class.load ‘b.rb’, m

p m::C
p C

harp:~ > cat b.rb
class C; end

harp:~ > ruby a.rb
#Module:0xb75cb50c::C
a.rb:24: uninitialized constant C (NameError)

i’d like to do the same for modules.

But in > any case I don’t feel the word “instantiated” is the right word for
the method. Note that I am not opposing the method itself.

how about #inherited then?

 harp:~ > ruby -e'  p Module.new.is_a?(Module)  '
 true

or perhaps #defined

or perhaps #created

regards.

-a

Francis C. wrote:

How about “included” instead of “instantiated”?

Defining SomeModule.included already does something quite different, so
it would be confusing to define Module#included.

Anyway, I think what he wanted was a callback that fires not when a
module is included, but when ruby evals this code:

module Foo
end

You can get this behavior for classes rather than modules: you get a
callback that fires for

class Bar
end

by defining the Class#inherited method (a global definition, with all
the inherent dangers), since Bar inherits (implicitly) from Object.

Hi,

In message “Re: module creation hook method (Re: [OT] Re: initializing
instance variables in a module)”
on Tue, 23 May 2006 16:23:23 +0900, Yukihiro M.
[email protected] writes:

|Or maybe invoking initialize at the module creation is even better.

Forget it. Module (and Class) already has its own initialize method
to call with Module.new (Class.new).

						matz.

Hi,

In message “Re: module creation hook method (Re: [OT] Re: initializing
instance variables in a module)”
on Tue, 23 May 2006 15:35:30 +0900, [email protected] writes:

| harp:~ > cat a.rb
| class Class
| WRAPPER = []
| def inherited other
| wrapper = WRAPPER.first
| wrapper.const_set other.name.split(%r/::/).last, other if wrapper
| end
| def load file, m
| wrapping(m){ ::Kernel.load file, wrap = true }
| end
| def wrapping m
| WRAPPER.push m
| yield
| ensure
| WRAPPER.pop
| end
| end
|
| m = Module.new
|
| Class.load ‘b.rb’, m
|
| p m::C
| p C

|i’d like to do the same for modules.

Thank you for the example. I am still not sure this is a right tool
for the right purpose, but I do understand what you wanted to do in
the code. Hidetoshi NAGAI is proposing load_to(file, module) method
to do the thing you wanted. In my opinion, this is better way to
implement.

| how about #inherited then?
|
| harp:~ > ruby -e’ p Module.new.is_a?(Module) ’
| true

I am not positive for this one. Since this is misleading people to
feel like modules are inherited from something.

| or perhaps #defined
| or perhaps #created

Maybe. Much better than inherited. Or maybe invoking initialize at
the module creation is even better.

						matz.

Yukihiro M. wrote:

Forget it. Module (and Class) already has its own initialize method
to call with Module.new (Class.new).

But it’s not called for the module Foo; end syntax:

irb(main):012:0> class Module; def initialize(*x) p x; end; end
=> nil
irb(main):013:0> Module.new
[]
=> #Module:0x2c87558
irb(main):014:0> module M; end
=> nil

Simon Kröger wrote:

t = Test.new
t.bar(‘baz’) << ‘eeek’
p t.bar(‘baz’)

Why not just

module Foo
def bar
@bar ||= Hash.new{|hsh, key| hsh[key] = []}
end
end

class Test
include Foo
end

test = Test.new
test.bar[:baz] << ‘bur’

a ||= b' returnsa’ or, if a' is nil,b’.

Daniel

Yukihiro M. wrote:

this issue. It is another option that adding a new hook like
‘module_initialize’ which is called at instantiation time for all
modules.

  					matz.

That would do the trick, and it would probably make the AOP people very
happy. But that is a bit different than an explicit module
initialization method. Is there a reason you don’t want
module_initialize or something like that?

CLOS does something like (defmethod rock :before …), right? Any ideas
on how the method combination would work in ruby?

Maybe using methods…

module Rocker
def pre_rock
puts ‘pre rock’
end

before :rock, :pre_rock
end

Or with syntax…

module Rocker
def before:rock
puts ‘pre rock’
end
end

class Foo
include Rocker

def rock
puts ‘We are rocking’
end
end

Foo.new.rock # => “pre rock\nWe are rocking\n”

-Jeff

2006/5/22, Jeff R. [email protected]:

end

Is there a standard or correct way to initialize @foo_the_stuff in this
example? Should the add_stuff method check whether the variable has
been initialized every time, or should this be done by implementing a
callback like append_features or included? (That’s how I’d want to do
it, but it’s not clear which or how…)

This thread seems to have gone astray a bit but I didn’t see this
solution which I regard the standard way to handle this. The important
part is to use initialize(*a,&b) in the module. I’ve put this on the
wiki for easier reference:

http://wiki.rubygarden.org/Ruby/page/show/InitializingWithInheritance

Kind regards

robert

On Tue, 23 May 2006, Yukihiro M. wrote:

Thank you for the example. I am still not sure this is a right tool for the
right purpose, but I do understand what you wanted to do in the code.
Hidetoshi NAGAI is proposing load_to(file, module) method to do the thing
you wanted. In my opinion, this is better way to implement.

indeed. that’s just one example though, a module/class creation hook
could be
used in all sorts of interesting ways:

class Module
def defined
STDERR.puts “#{ self } defined @ #{ caller.first }”
end
end

for instance.

| or perhaps #defined
| or perhaps #created

Maybe. Much better than inherited. Or maybe invoking initialize at
the module creation is even better.

(after you reading your other note)

yes. #defined would be really nice for both classes and modules -
called via
rb_define_xxx.

cheers.

-a

Robert K. wrote:

This thread seems to have gone astray a bit but I didn’t see this
solution which I regard the standard way to handle this. The important
part is to use initialize(*a,&b) in the module. I’ve put this on the
wiki for easier reference:

http://wiki.rubygarden.org/Ruby/page/show/InitializingWithInheritance

Nice writeup. I especially like that you captured the need to
tranparently pass arguments thru the module initializer. That’s easy to
miss at first glance.


– Jim W.

This thread seems to have gone astray a bit but I didn’t see this
solution which I regard the standard way to handle this. The important
part is to use initialize(*a,&b) in the module. I’ve put this on the
wiki for easier reference:

http://wiki.rubygarden.org/Ruby/page/show/InitializingWithInheritance

Kind regards

robert

This doesn’t really solve the problem. The idea is that you don’t want
the including class to have to do anything related to initialization of
the module(s) being included. In your example any including class would
have to call super in order to make it work. If Derived implements an
initialize method and doesn’t call super then the module isn’t
initialized. But why should it call super, it isn’t deriving from
anything, it is mixing it in.

The two options Matz mentioned are the way to go. Either a callback
(module_initialize), which will act as an initialization method for the
module, or the ability for the module to insert its own method(s)
before, after, or around the class that includes it. (CLOS method
combinations… AOP)

-Jeff

[email protected] wrote:

yes. #defined would be really nice for both classes and modules -
called via
rb_define_xxx.

This is sort of a tangent, but what about a const_added hook? That
wouldn’t fire when Module.new is called, though. And it would mean
having to ignore non-class/module constants.

On Wed, 24 May 2006, Joel VanderWerf wrote:

[email protected] wrote:

yes. #defined would be really nice for both classes and modules -
called via
rb_define_xxx.

This is sort of a tangent, but what about a const_added hook? That
wouldn’t fire when Module.new is called, though. And it would mean
having to ignore non-class/module constants.

hmmm. i like this - are you sure that’s the hook name?

harp:~ > cat a.rb
class Object
def const_added *a, &b
p a, b
end
end

load ‘b.rb’, anon = true

harp:~ > cat b.rb
class C; end

harp:~ > ruby a.rb

i also tried in Module and Class - no joy.

thoughts?

-a

[email protected] wrote:

On Wed, 24 May 2006, Joel VanderWerf wrote:

This is sort of a tangent, but what about a const_added hook? That
wouldn’t fire when Module.new is called, though. And it would mean
having to ignore non-class/module constants.

hmmm. i like this - are you sure that’s the hook name?

Sorry … it was just a wild suggestion. There’s nothing like that now,
AFAIK.

It’s too bad set_trace_func slows down the interpreter, but you could
use that to catch “class” events: “start a class or module definition”
according to the docs.

2006/5/23, Jeff R. [email protected]:

This doesn’t really solve the problem. The idea is that you don’t want
the including class to have to do anything related to initialization of
the module(s) being included.

It doesn’t have to.

In your example any including class would
have to call super in order to make it work.

But this is true for classes inheriting anyway. You could even make it
yourself a habit to even call super if you do not inherit specifically
(i.e. inherit Obect).

If Derived implements an
initialize method and doesn’t call super then the module isn’t
initialized. But why should it call super, it isn’t deriving from
anything, it is mixing it in.

I don’t fully agree: Derived actually inherits from Base so it’s
standard procedure to invoke the super class initialize. If you then
write your module initialize with signature (*a,&b) you can insert it
into any inheritance chain that obeys the basic behavior without
doing any harm or losing initialization code.

The two options Matz mentioned are the way to go. Either a callback
(module_initialize), which will act as an initialization method for the
module, or the ability for the module to insert its own method(s)
before, after, or around the class that includes it. (CLOS method
combinations… AOP)

Well, yes, if a change to the language / lib can be considered these
are probably better.

Kind regards

robert