Bending ruby space

i came upon this "pattern" working on a rather difficult problem. see
if you can wrap your head around this bending of ruby space and what it
might be good for.

  module R; end
  module U; include R; end
  module R; extend U; end

t.

Trans wrote:

i came upon this "pattern" working on a rather difficult problem. see
if you can wrap your head around this bending of ruby space and what it
might be good for.

  module R; end
  module U; include R; end
  module R; extend U; end

why not:
module R; extend self end
or just:
module R; module_function; ... end
?

Devin
(Thas right, biatches. extend self is the new class << self.)

Job security? :wink:

···

On Dec 9, 2:51 pm, "Trans" <transf...@gmail.com> wrote:

see
if you can wrap your head around this bending of ruby space and what it
might be good for.

  module R; end
  module U; include R; end
  module R; extend U; end

one side effect is that all instance methods of R are available at the module
level too. i generally do that this way:

   harp:~ > cat a.rb
   class Module
     def export meth
       module_function meth
       public meth
     end
   end

   module R
     def foo() 42 end
     export :foo
   end

   p R.foo

   harp:~ > ruby a.rb
   42

what that what you were after, but wholesale?

interesting trick.

regards.

-a

···

On Sun, 10 Dec 2006, Trans wrote:

i came upon this "pattern" working on a rather difficult problem. see
if you can wrap your head around this bending of ruby space and what it
might be good for.

module R; end
module U; include R; end
module R; extend U; end

--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama

Hi --

···

On Sun, 10 Dec 2006, Devin Mullins wrote:

Trans wrote:

i came upon this "pattern" working on a rather difficult problem. see
if you can wrap your head around this bending of ruby space and what it
might be good for.

  module R; end
  module U; include R; end
  module R; extend U; end

why not:
module R; extend self end
or just:
module R; module_function; ... end
?

Devin
(Thas right, biatches. extend self is the new class << self.)

I'm not sure what you mean. extend self doesn't do what class << self
does. Am I misunderstanding?

David

--
                   David A. Black | dblack@wobblini.net
Author of "Ruby for Rails" [1] | Ruby/Rails training & consultancy [3]
DABlog (DAB's Weblog) [2] | Co-director, Ruby Central, Inc. [4]
[1] Ruby for Rails | [3] http://www.rubypowerandlight.com
[2] http://dablog.rubypal.com | [4] http://www.rubycentral.org

John Wilger wrote:

> see
> if you can wrap your head around this bending of ruby space and what it
> might be good for.
>
> module R; end
> module U; include R; end
> module R; extend U; end

Job security? :wink:

LOL! :smiley:

Okay. When my headache goes away I'll tell you too how you can secure
your job :wink:

T.

            .---------.
  david | the box | me ->
  black most people
            '---------'

···

On Dec 9, 2:51 pm, "Trans" <transf...@gmail.com> wrote:

that's an interesting method in it's own right. i'm tempted to add to
facets, though maybe the name isn't the best. I say that only b/c I've
been using #import to load a lib directly into the current module
space. and it would seem to me #import and #export should have some
related usage --one way or the other.

in any case you all are partly right of course. but the neat part of
this --the real "bending" and the reason it uses two modules the way
it does....

  module R; end
  module U; include R; end
  module R; extend U; end

  module R
    def x; "x"; end
  end

  module U
    def x; "{" + super + "}"; end
  end

  R.x #=> "{x}"

the effect is *dynamic* AOP wrapping of R by U. it is dynamic b/c it is
possible to define the "aspect" U prior to any corresponding method in
R. (btw, 'if defined?(super)' is helpful in such cases). I used this
myself to cache specifically named methods that may, or may not, be in
a user-defined code snippet.
it is unfortuate however that, afaict, the same pattern can't be used
on a class --just a module.

t.

···

ara.t.howard@noaa.gov wrote:

On Sun, 10 Dec 2006, Trans wrote:

> i came upon this "pattern" working on a rather difficult problem. see
> if you can wrap your head around this bending of ruby space and what it
> might be good for.
>
> module R; end
> module U; include R; end
> module R; extend U; end

one side effect is that all instance methods of R are available at the module
level too. i generally do that this way:

   harp:~ > cat a.rb
   class Module
     def export meth
       module_function meth
       public meth
     end
   end

   module R
     def foo() 42 end
     export :foo
   end

speaking of this "export" method, how does one do that for a whole
module? ie. adding one module_finction module to another.

  module X
    module_function
    def f; "f"; end
  end

  module Q
    module_function
    include X
    extend X
  end

but that doesn't work b/c

  Q.f #=> ERROR: private method `f' called for Q:Module

t.

···

ara.t.howard@noaa.gov wrote:

On Sun, 10 Dec 2006, Trans wrote:

> i came upon this "pattern" working on a rather difficult problem. see
> if you can wrap your head around this bending of ruby space and what it
> might be good for.
>
> module R; end
> module U; include R; end
> module R; extend U; end

one side effect is that all instance methods of R are available at the module
level too. i generally do that this way:

   harp:~ > cat a.rb
   class Module
     def export meth
       module_function meth
       public meth
     end
   end

   module R
     def foo() 42 end
     export :foo
   end

   p R.foo

   harp:~ > ruby a.rb
   42

dblack@wobblini.net wrote:

I'm not sure what you mean. extend self doesn't do what class << self
does. Am I misunderstanding?

It was a "green is the new blue" parody. Not a funny one, mind you, but the use of "biatches" should've warned you of that.

Devin

dynamically injectable 'super' - very useful.

cheers.

-a

···

On Mon, 11 Dec 2006, Trans wrote:

in any case you all are partly right of course. but the neat part of
this --the real "bending" and the reason it uses two modules the way
it does....

module R; end
module U; include R; end
module R; extend U; end

module R
   def x; "x"; end
end

module U
   def x; "{" + super + "}"; end
end

R.x #=> "{x}"

the effect is *dynamic* AOP wrapping of R by U. it is dynamic b/c it is
possible to define the "aspect" U prior to any corresponding method in
R. (btw, 'if defined?(super)' is helpful in such cases). I used this
myself to cache specifically named methods that may, or may not, be in
a user-defined code snippet.
it is unfortuate however that, afaict, the same pattern can't be used
on a class --just a module.

--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama

harp:~ > cat a.rb
     module X
       module_function # side effect -> instance 'f' made private
       def f; "f"; end
       public :f
     # ^^^^^^ ^^
     end

     module Q
       module_function
       include X
       extend X
     end

     p Q.f

     p Object.new.instance_eval{ extend Q and self }.f

     include Q
     p f

     harp:~ > ruby a.rb
     "f"

regards.

-a

···

On Tue, 12 Dec 2006, Trans wrote:

speaking of this "export" method, how does one do that for a whole
module? ie. adding one module_finction module to another.

module X
   module_function
   def f; "f"; end
end

module Q
   module_function
   include X
   extend X
end

but that doesn't work b/c

Q.f #=> ERROR: private method `f' called for Q:Module

t.

--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama

but that undoes the module_function-ality of X.

t.

···

ara.t.howard@noaa.gov wrote:

     harp:~ > cat a.rb
     module X
       module_function # side effect -> instance 'f' made private
       def f; "f"; end
       public :f
     # ^^^^^^ ^^
     # ^^^^^^ ^^
     # ^^^^^^ ^^
     end

??

harp:~ > cat a.rb
module X
   module_function # side effect -> instance 'f' made private
   def f; "f"; end
   public :f
end

p X.f

include X
p self.f

harp:~ > ruby a.rb
"f"

-a

···

On Tue, 12 Dec 2006, Trans wrote:

ara.t.howard@noaa.gov wrote:

     harp:~ > cat a.rb
     module X
       module_function # side effect -> instance 'f' made private
       def f; "f"; end
       public :f
     # ^^^^^^ ^^
     end

but that undoes the module_function-ality of X.

--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama

Exactly. Here let me give an actual example to help explain:

  module CompressUtils
    module_function
    def tar_gz( folder, to_file=nil )
      # ...
    end
  end

I need CompressUtils to stay as is so as to work on it's own as a
function module. But in one case I was thinking of doing:

  module FileUtils
    include_extend_or_whatever CompressUtils
  end

With the desired effect being is as if I had originially done:

  module FileUtils
    module_function
    def tar_gz( folder, to_file=nil )
      # ...
    end
  end

t.

···

ara.t.howard@noaa.gov wrote:

On Tue, 12 Dec 2006, Trans wrote:

>
> ara.t.howard@noaa.gov wrote:
>> harp:~ > cat a.rb
>> module X
>> module_function # side effect -> instance 'f' made private
>> def f; "f"; end
>> public :f
>> # ^^^^^^ ^^
>> # ^^^^^^ ^^
>> # ^^^^^^ ^^
>> end
>
> but that undoes the module_function-ality of X.

??

harp:~ > cat a.rb
module X
   module_function # side effect -> instance 'f' made private
   def f; "f"; end
   public :f
end

ah. i use this alot, it's concise and extremely powerful:

   harp:~ > cat a.rb
   module CompressUtils
     module Methods
       def tar_gz folder, to_file=nil
         p [ folder, to_file ]
       end
     end
     module ClassMethods
       include Methods
     end
     module InstanceMethods
       include Methods
     end
     def self.included other
       other.module_eval{
         include InstanceMethods if defined? InstanceMethods
         extend ClassMethods if defined? ClassMethods
         def self.included other
           other.module_eval{
             include InstanceMethods if defined? InstanceMethods
             extend ClassMethods if defined? ClassMethods
           }
         end
       }
     end
   end

   module FileUtils
     include CompressUtils
   end

   FileUtils.tar_gz '/', 'a.tgz'

   include FileUtils
   tar_gz '/', 'a.tgz'
   self.class.tar_gz '/', 'a.tgz'

   harp:~ > ruby a.rb
   ["/", "a.tgz"]

-a

···

On Tue, 12 Dec 2006, Trans wrote:

Exactly. Here let me give an actual example to help explain:

module CompressUtils
   module_function
   def tar_gz( folder, to_file=nil )
     # ...
   end
end

I need CompressUtils to stay as is so as to work on it's own as a
function module. But in one case I was thinking of doing:

module FileUtils
   include_extend_or_whatever CompressUtils
end

With the desired effect being is as if I had originially done:

module FileUtils
   module_function
   def tar_gz( folder, to_file=nil )
     # ...
   end
end

t.

--
if you want others to be happy, practice compassion.
if you want to be happy, practice compassion. -- the dalai lama

ah. yes i know this pattern. though i prefer #class_extension myself.
still not quite what i'm after but your sample helped jog my brain in
the right direction --thanks. i *think* this does it:

  module CompressUtils
    module_function
    ...
  end

  module FileUtils
    include CompressUtils
    module_function *(CompressUtils.private_instance_methods &
CompressUtils.methods(false))
  end

that seem about right?

t.

···

ara.t.howard@noaa.gov wrote:

On Tue, 12 Dec 2006, Trans wrote:

> Exactly. Here let me give an actual example to help explain:
>
> module CompressUtils
> module_function
> def tar_gz( folder, to_file=nil )
> # ...
> end
> end
>
> I need CompressUtils to stay as is so as to work on it's own as a
> function module. But in one case I was thinking of doing:
>
> module FileUtils
> include_extend_or_whatever CompressUtils
> end
>
> With the desired effect being is as if I had originially done:
>
> module FileUtils
> module_function
> def tar_gz( folder, to_file=nil )
> # ...
> end
> end
>
> t.

ah. i use this alot, it's concise and extremely powerful:

   harp:~ > cat a.rb
   module CompressUtils
     module Methods
       def tar_gz folder, to_file=nil
         p [ folder, to_file ]
       end
     end
     module ClassMethods
       include Methods
     end
     module InstanceMethods
       include Methods
     end
     def self.included other
       other.module_eval{
         include InstanceMethods if defined? InstanceMethods
         extend ClassMethods if defined? ClassMethods
         def self.included other
           other.module_eval{
             include InstanceMethods if defined? InstanceMethods
             extend ClassMethods if defined? ClassMethods
           }
         end
       }
     end
   end

   module FileUtils
     include CompressUtils
   end

   FileUtils.tar_gz '/', 'a.tgz'

   include FileUtils
   tar_gz '/', 'a.tgz'
   self.class.tar_gz '/', 'a.tgz'

   harp:~ > ruby a.rb
   ["/", "a.tgz"]
   ["/", "a.tgz"]
   ["/", "a.tgz"]