Initializing instance variables in a module

How about "included" instead of "instantiated"?

···

On 5/23/06, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

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.

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

···

On Tue, 23 May 2006, Yukihiro Matsumoto wrote:
--
be kind whenever possible... it is always possible.
- h.h. the 14th dali lama

Hi --

···

On Tue, 23 May 2006, Simon Kröger wrote:

Francis Cianfrocca schrieb:

You still have to call it every time you use the variable.

Do you realy need to use the variable directly?
My scripts tend to have very little use of '@'.

module Foo
def bar(key)
  @myvar ||= Hash.new {|k,v| k[v] = }
  @myvar[key]
end

class Test
include Foo
end

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

I didn't followed the whole thread so please ignore me
if this was suggested before.

It was -- that, or a close variant, was what I don't understand the
non-usefulness of, but although I've read the thread I think there's
some level of complexity I haven't caught sight of.

David

--
David A. Black (dblack@wobblini.net)
* Ruby Power and Light, LLC (http://www.rubypowerandlight.com)
   > Ruby and Rails consultancy and training
* Author of "Ruby for Rails" from Manning Publications!
   > Ruby for Rails

Looks promising but what if you have to assign to the variable? This code
throws an exception:

module Mixin
  def myvar
    @myvar ||= 100
    @myvar
  end

  def inc_myvar
    myvar += 1
  end
end

class Klass
  include Mixin
end

Klass.new.inc_myvar

···

On 5/22/06, Simon Kröger <SimonKroeger@gmx.de> wrote:

Francis Cianfrocca schrieb:
> You still have to call it every time you use the variable.
>

Do you realy need to use the variable directly?
My scripts tend to have very little use of '@'.

module Foo
def bar(key)
   @myvar ||= Hash.new {|k,v| k[v] = }
   @myvar[key]
end

class Test
  include Foo
end

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

I didn't followed the whole thread so please ignore me
if this was suggested before.

cheers

Simon

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

···

On 5/23/06, Yukihiro Matsumoto <matz@ruby-lang.org> wrote:

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.

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

Hi,

  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.

···

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, ara.t.howard@noaa.gov writes:

Simon Kröger wrote:

module Foo
def bar(key)
   @myvar ||= Hash.new {|k,v| k[v] = }
   @myvar[key]
end
end

class Test
  include Foo
end

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' returns `a' or, if `a' is nil, `b'.

Daniel

Francis Cianfrocca wrote:

Looks promising but what if you have to assign to the variable? This code
throws an exception:

module Mixin
def myvar
   @myvar ||= 100
   @myvar
end

def inc_myvar
   myvar += 1

     self.myvar += 1

···

end
end

class Klass
include Mixin
end

Klass.new.inc_myvar

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

harp:~ > cat a.rb
   require 'traits'

   module Mixin
     trait 'myvar' => 100

     def inc_myvar() myvar( myvar + 1) end
   end

   class Klass
     include Mixin
   end

   p Klass.new.inc_myvar

   harp:~ > ruby a.rb
   101

-a

···

On Tue, 23 May 2006, Francis Cianfrocca wrote:

Looks promising but what if you have to assign to the variable? This code
throws an exception:

module Mixin
def myvar
  @myvar ||= 100
  @myvar
end

def inc_myvar
  myvar += 1
end

class Klass
include Mixin
end

Klass.new.inc_myvar

--
be kind whenever possible... it is always possible.
- h.h. the 14th dali lama

Francis Cianfrocca wrote:

Looks promising but what if you have to assign to the variable? This code
throws an exception:

[...]

def inc_myvar
   myvar += 1
end
end

this is equivalent to

myvar = myvar + 1

which tries to initialize a *local* variable, thats not what you want.
try self.myvar += 1

this of course does only work if you define a setter for myvar.

module Mixin
attr_writer :myvar

def myvar
   @myvar ||= 100
   @myvar
end

def inc_myvar
   self.myvar += 1
end
end

class Klass
include Mixin
end

Klass.new.inc_myvar

cheers

Simon

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 Matsumoto <matz@ruby-lang.org> 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.

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

···

On Tue, 23 May 2006, Yukihiro Matsumoto wrote:
--
be kind whenever possible... it is always possible.
- h.h. the 14th dali lama

Joel VanderWerf wrote:

Francis Cianfrocca wrote:

Looks promising but what if you have to assign to the variable? This code
throws an exception:

module Mixin
def myvar
   @myvar ||= 100
   @myvar
end

Oops... forgot this, obviously (attr_writer is an alternative):

    def myvar=(val)
      @myvar = val
    end

···

def inc_myvar
   myvar += 1

     self.myvar += 1

end
end

class Klass
include Mixin
end

Klass.new.inc_myvar

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

We've definitely wandered into one of Ruby's darker, mustier corners. None
of these solutions really sing.

···

On 5/22/06, ara.t.howard@noaa.gov <ara.t.howard@noaa.gov> wrote:

On Tue, 23 May 2006, Francis Cianfrocca wrote:

> Looks promising but what if you have to assign to the variable? This
code
> throws an exception:
>
> module Mixin
> def myvar
> @myvar ||= 100
> @myvar
> end
>
> def inc_myvar
> myvar += 1
> end
>
> class Klass
> include Mixin
> end
>
> Klass.new.inc_myvar

   harp:~ > cat a.rb
   require 'traits'

   module Mixin
     trait 'myvar' => 100

     def inc_myvar() myvar( myvar + 1) end
   end

   class Klass
     include Mixin
   end

   p Klass.new.inc_myvar

   harp:~ > ruby a.rb
   101

-a
--
be kind whenever possible... it is always possible.
- h.h. the 14th dali lama

Yukihiro Matsumoto 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

···

--
http://flgr.0x42.net/

...

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.

···

ara.t.howard@noaa.gov wrote:

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407

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

···

On Wed, 24 May 2006, Joel VanderWerf wrote:

ara.t.howard@noaa.gov 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.

--
be kind whenever possible... it is always possible.
- h.h. the 14th dali lama

...

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.

···

ara.t.howard@noaa.gov wrote:

On Wed, 24 May 2006, Joel VanderWerf wrote:

--
      vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407