Module.nesting -> Kernel#nesting

Discussion in 'Ruby' started by Trans, Aug 16, 2005.

  1. Trans

    Trans Guest

    I'm trying to write a little method called Module#modspace, which will
    return the module/class a module/class is defined in. I.e.

    Module X
    Module Y
    Module Z
    end
    end
    end

    X::Y::Z.modspace #=> X::Y


    So I thought, Module.nesting would help do the trick. But I discovered
    the Module.nesting returns the nesting according where it is called in
    the code, nothing more. It is like __LINE__ or __FILE__ in this
    respect. So it seems to me that it would be more appropriate to define
    #nesting in Kernel, not as a class method of Module.

    BTW, any help writing Module#modspace appreciated.

    T.
    Trans, Aug 16, 2005
    #1
    1. Advertising

  2. ---- Original message from Trans on 8/16/2005 2:36 PM:

    >I'm trying to write a little method called Module#modspace, which will
    >return the module/class a module/class is defined in. I.e.
    >
    > Module X
    > Module Y
    > Module Z
    > end
    > end
    > end
    >
    > X::Y::Z.modspace #=> X::Y
    >
    >
    >So I thought, Module.nesting would help do the trick. But I discovered
    >the Module.nesting returns the nesting according where it is called in
    >the code, nothing more. It is like __LINE__ or __FILE__ in this
    >respect. So it seems to me that it would be more appropriate to define
    >#nesting in Kernel, not as a class method of Module.
    >
    >
    >
    >

    This is mostlikely not the best way to do it, but here is a way to get
    at the information.

    class Module
    def lineage
    eval self.ancestors.to_s.sub( /::[^:]$/, "" )
    end
    def modspace
    lineage
    end
    end

    module X
    module Y
    module Z
    end
    end
    end

    a = X::Y::Z

    p a.modspace
    p a.modspace.class
    Dale Martenson, Aug 16, 2005
    #2
    1. Advertising

  3. Dale Martenson wrote:
    > class Module
    > def lineage
    > eval self.ancestors.to_s.sub( /::[^:]$/, "" )


    You can use name.sub(...) instead of self.ancestors.to_s.sub(...), but
    it's not much better.

    --
    vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407
    Joel VanderWerf, Aug 16, 2005
    #3
  4. ---- Original message from Joel VanderWerf on 8/16/2005 5:04 PM:

    >Dale Martenson wrote:
    >
    >
    >>class Module
    >> def lineage
    >> eval self.ancestors.to_s.sub( /::[^:]$/, "" )
    >>
    >>

    >
    >You can use name.sub(...) instead of self.ancestors.to_s.sub(...), but
    >it's not much better.
    >
    >
    >

    Actually, it is a lot better since you avoid cases where there are
    additional includes. Module#ancestors
    returns an array which causes problems with my original suggestion.

    Example:

    module X
    include Math
    module Y
    include Comparable
    module Z
    include Enumerable
    end
    end
    end

    Thanks, Joel for your suggestion. For some reason, Module#name just
    didn't come to mind.
    Dale Martenson, Aug 16, 2005
    #4
  5. Trans

    Trans Guest

    Nice use of #eval. That's what I was missing. ( I usually try to avoid
    #eval, but in this case it makes it much easier).

    Thanks,
    T.

    P.S. Anyone on why #nesting isn't in Kernel?
    Trans, Aug 17, 2005
    #5
  6. Trans

    Pit Capitain Guest

    Trans schrieb:
    > P.S. Anyone on why #nesting isn't in Kernel?


    Maybe because the only thing you can nest are modules, and the result is
    a list of modules? IMO, it has nothing to do with general objects.

    Regards,
    Pit
    Pit Capitain, Aug 17, 2005
    #6
  7. Trans

    Trans Guest

    Pit Capitain wrote:
    > Trans schrieb:
    > > P.S. Anyone on why #nesting isn't in Kernel?

    >
    > Maybe because the only thing you can nest are modules, and the result is
    > a list of modules? IMO, it has nothing to do with general objects.


    Actually that's my point. What you say is the common general thought,
    it's exactly what I had thought, but it's isn't true. #nesting actually
    has nothing to do with it's reciever 'class Module'. And has more do
    with the object, namely, the nesting from _that place in the object_,
    well, at least as much as __LINE__ and __FILE__ do. By analogy, we
    don't use 'File.__LINE__'. Do you see what I'm getting at?

    Kernel is not so much a mixin of Object, as it is a omni-accessible
    toolchest for the Ruby coder.

    T.
    Trans, Aug 17, 2005
    #7
  8. Trans

    Pit Capitain Guest

    Trans schrieb:
    >Pit Capitain wrote:
    >>Trans schrieb:
    >>
    >>>P.S. Anyone on why #nesting isn't in Kernel?

    >>
    >>Maybe because the only thing you can nest are modules, and the result is
    >>a list of modules? IMO, it has nothing to do with general objects.

    >
    > Actually that's my point. What you say is the common general thought,
    > it's exactly what I had thought, but it's isn't true. #nesting actually
    > has nothing to do with it's reciever 'class Module'.


    Seems I can't express my thoughts very well. I know that Module.nesting
    isn't an instance method of Module and that you can't ask an instance of
    Module for its nesting.

    What I wanted to say is that the value of Module.nesting depends only on
    the nesting of module definitions. It only matters in which (lexical)
    module context it is called. It has nothing to do with other objects. If
    you'd remove the class Module from Ruby, a nesting method wouldn't make
    sense anymore.

    > And has more do
    > with the object, namely, the nesting from _that place in the object_,
    > well, at least as much as __LINE__ and __FILE__ do. By analogy, we
    > don't use 'File.__LINE__'. Do you see what I'm getting at?


    Yes, but you could remove the class File from Ruby and it would still
    make sense to get the name of the current source file. The current
    source file is a property of the compile time environment and has
    nothing to do with any Ruby language constructs. From this point of view
    it wouldn't make sense to associate __FILE__ with the Ruby class File.

    > Kernel is not so much a mixin of Object, as it is a omni-accessible
    > toolchest for the Ruby coder.


    But __FILE__ is a token recognized by the parser. It is neither a
    constant nor a method of any module, including Kernel.

    As always just my 2 cents.

    Regards,
    Pit
    Pit Capitain, Aug 17, 2005
    #8
  9. Trans

    Trans Guest

    > But __FILE__ is a token recognized by the parser. It is neither a
    > constant nor a method of any module, including Kernel.


    True. But if you were to try to define it yourself it woul be a Kernel
    module.

    Anyway, I've come back to this old thread b/c I realize now, why
    exactly this would be more approriate as a Kernel method and not a
    Module method: the definition requires a "Binding.of_caller" in order
    to work --ie. if one were to try to do it in ruby themselves. So
    underthehood it must be doing the same. Since Binding.of_caller is
    considered "not good" (do I understand correctly that matz has
    declined this functionality for Ruby?) then this method goes against
    that grain.

    How did I realize this? I was trying to write an Ruby interpolate
    method as a String module function. And for the same reason it was not
    possible --I had to put it in Kernel.

    T.
    Trans, Sep 16, 2005
    #9
  10. Trans

    Trans Guest

    Trans wrote:
    > > But __FILE__ is a token recognized by the parser. It is neither a
    > > constant nor a method of any module, including Kernel.

    >
    > True. But if you were to try to define it yourself it woul be a Kernel
    > module.
    >
    > Anyway, I've come back to this old thread b/c I realize now, why
    > exactly this would be more approriate as a Kernel method and not a
    > Module method: the definition requires a "Binding.of_caller" in order
    > to work --ie. if one were to try to do it in ruby themselves. So
    > underthehood it must be doing the same. Since Binding.of_caller is
    > considered "not good" (do I understand correctly that matz has
    > declined this functionality for Ruby?) then this method goes against
    > that grain.
    >
    > How did I realize this? I was trying to write an Ruby interpolate
    > method as a String module function. And for the same reason it was not
    > possible --I had to put it in Kernel.


    Well, I'll correct myself. Techincally, you still need
    Binding.of_caller using Kernel. It's just that Kernel's modus operandi
    is functionality unversally present, so it seems like the right place.

    T.
    Trans, Sep 16, 2005
    #10
  11. This does the same job without using eval:

    class Module
    def lineage
    name.split(/::/)[0..-2].inject(self) do |mod, modname|
    mod.const_get(modname)
    end
    end
    def modspace
    lineage
    end
    end

    module X
    include Math
    module Y
    include Comparable
    module Z
    include Enumerable
    end
    end
    end

    x =3D X
    y =3D X::Y
    z =3D X::Y::Z

    p x.modspace
    p x.modspace.class

    p y.modspace
    p y.modspace.class

    p z.modspace
    p z.modspace.class

    __END__
    ---------- Ruby ----------
    X
    Module
    X
    Module
    X::Y
    Module

    Output completed (0 sec consumed) - Normal Termination

    Not that I think eval is evil. I find it very handy.

    I'm not sure what it means for X's modspace (aka 'lineage') to be X but tha=
    t's
    how the original worked. Perhaps it should be Module?
    You can get this behaviour by changing inject(self) to inject(Module).

    I'm curious - what would you do with this?

    Regards

    Sean
    Sean O'Halpin, Sep 16, 2005
    #11
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. yogesh
    Replies:
    3
    Views:
    587
    Kenny McCormack
    Feb 12, 2006
  2. kernel module: beginner

    , Jun 28, 2006, in forum: C Programming
    Replies:
    3
    Views:
    347
    Joe Estock
    Jun 28, 2006
  3. gga
    Replies:
    3
    Views:
    157
    William Morgan
    Feb 19, 2005
  4. Replies:
    3
    Views:
    169
  5. Lars Gierth
    Replies:
    6
    Views:
    221
    David Masover
    Mar 20, 2010
Loading...

Share This Page