Ruby Forum Ruby > bending ruby space

Posted by Trans (Guest)
on 09.12.2006 23:52
(Received via mailing list)
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.
Posted by Devin Mullins (twifkak)
on 10.12.2006 01:42
(Received via mailing list)
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.)
Posted by unknown (Guest)
on 10.12.2006 04:16
(Received via mailing list)
Hi --

On Sun, 10 Dec 2006, Devin Mullins wrote:

> 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
Posted by John Wilger (jwilger)
on 10.12.2006 04:20
(Received via mailing list)
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

Job security? ;-)
Posted by Trans (Guest)
on 10.12.2006 04:32
(Received via mailing list)
John Wilger wrote:
> 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
>
> Job security? ;-)

LOL! :-D

Okay. When my headache goes away I'll tell you too how you can secure
your job ;-)

T.


            .---------.
  david     | the box |                                 me ->
  black     most people
            '---------'
Posted by Devin Mullins (twifkak)
on 10.12.2006 05:22
(Received via mailing list)
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
Posted by unknown (Guest)
on 10.12.2006 06:10
(Received via mailing list)
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

what that what you were after, but wholesale?

interesting trick.

regards.

-a
Posted by Trans (Guest)
on 10.12.2006 17:45
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
> one side effect is that all instance methods of R are available at the module
>    module R
>      def foo() 42 end
>      export :foo
>    end

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.
Posted by unknown (Guest)
on 10.12.2006 18:09
(Received via mailing list)
On Mon, 11 Dec 2006, Trans wrote:

>  end
> 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.

dynamically injectable 'super' - very useful.

cheers.

-a
Posted by Trans (Guest)
on 11.12.2006 16:45
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
> one side effect is that all instance methods of R are available at the module
>    module R
>      def foo() 42 end
>      export :foo
>    end
>
>    p R.foo
>
>    harp:~ > ruby a.rb
>    42

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.
Posted by unknown (Guest)
on 11.12.2006 17:05
(Received via mailing list)
On Tue, 12 Dec 2006, Trans wrote:

>    include X
>    extend X
>  end
>
> but that doesn't work b/c
>
>  Q.f #=>  ERROR: private method `f' called for Q:Module
>
> t.


     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"
     "f"
     "f"


regards.

-a
Posted by Trans (Guest)
on 11.12.2006 18:35
(Received via mailing list)
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.

t.
Posted by unknown (Guest)
on 11.12.2006 18:55
(Received via mailing list)
On Tue, 12 Dec 2006, Trans wrote:

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


p X.f

include X
p self.f


harp:~ > ruby a.rb
"f"
"f"


-a
Posted by Trans (Guest)
on 11.12.2006 20:11
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
> >>      # ^^^^^^ ^^
>    def f; "f"; end
>    public :f
> end

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.
Posted by unknown (Guest)
on 11.12.2006 21:19
(Received via mailing list)
On Tue, 12 Dec 2006, Trans wrote:

> function module. But in one case I was thinking of doing:
>      # ...
>    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"]


-a
Posted by Trans (Guest)
on 12.12.2006 00:08
(Received via mailing list)
ara.t.howard@noaa.gov wrote:
> >
> >    module_function
>    harp:~ > cat a.rb
>        include Methods
>          end
>    include FileUtils
>    tar_gz '/', 'a.tgz'
>    self.class.tar_gz '/', 'a.tgz'
>
>
>    harp:~ > ruby a.rb
>    ["/", "a.tgz"]
>    ["/", "a.tgz"]
>    ["/", "a.tgz"]

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.