On 6/24/07, Trans <transfire / gmail.com> wrote:
>
>
> On Jun 24, 4:15 am, "Robert Dober" <robert.do... / gmail.com> wrote:
> > On 6/24/07, Trans <transf... / gmail.com> wrote:
> >
> >
> >
> > > Well, I might as well bring up the reason I asked about enum_obj...
> >
> > > Spending some time improving Facets' Elementor class concept and
> > > #every method, I find this possible utter simplification:
> >
> > >   class Enumerable::Enumerator
> > >     def method_missing(sym, *args, &blk)
> > >       self.class.new(collect{ |e| e.send(sym, *args, &blk) })
> > >     end
> > >   end
> >
> > > Example:
> >
> > >   a = [1,2,3]
> > >   e = a.to_enum
> > >   e += 3
> > >   e *= 2
> > >   e.to_a #=> [8,10,11]
> >
> > > T.
> >
> > Apart the magic dot notation that is *exactly* what I am doing in Labrador.
> > Well I cannot expect blocks in this way as they have the original
> > purpose and are sent to map.
> >
> > module Enumerable
> >
> >   alias_method :__map_l1, :map
> >   #
> >   # The behavior of map {...} is unchanged.
> >   # map(arg1, *rest) simply is translated to map{ |ele| ele.send(arg1, *rest) }
> >   # map(arg1, *rest){...} is translated to map{|ele|
> > ele.send(arg1,*rest}.map{...}
> >   # map without any arguments creates a Dispatcher Proxy that will
> > dispatch all messages
> >   #   to the elements of  the receiver.
> >   #
> >   # All the following expressions evaluate therefore to the same result:
> >   #   ary=[*0..9]
> >   #   ary.map{ |x| x + 1}
> >   #   ary.map(:succ)
> >   #   ary.map.succ
> >   #   ary.map(:+, 1)
> >   #   ary.map + 1
> >   def map *args, &blk
> >     return Labrador::Dispatcher.new( self, :map ) if args.empty? && blk.nil?
> >     return __map_l1( &blk ) if args.empty?
> >     return __map_l1 { |x| x.send( *args ) } if blk.nil?
> >     __map_l1 { |x| x.send( *args ) }.__map_l1( &blk )
> >   end # def map *args, &blk
> >
> > end # module Enumerable
>
> Ah, so you overloaded #map with this functionality. That's similar to
> what I had done, but I used a different method name, #every, which is
> defined:
Facets is great but Labrador is mine, what does that mean: I have the
luxury to do things that scale badly and break compatibility, -- I
have to make the documentation clear about this in the next version.
Facets is a General Purpose Library and cannot afford that luxury, so
it is very clear why you have #every -- a tempting idea not to
overload map, even in an experimental package as my dog package. Yet
another advantage, I just change the name, nobody can complain...
OTH I am surprised that #every corresponds to #map, from its naming on
would say it should correspond to #each.
>
>   module Enumerable
>     def every
>       @_functor_every ||= Functor.new do |op,*args|
>         self.collect{ |a| a.send(op,*args) }
>       end
>     end
>   end
>
I gotta look at your Functors again, maybe I can steal a little bit from you;)
> Both are limited in one common respect. They can't be chained along
> without repeated invocation, eg. it's not
>
>   [1,2,3].map * 6 + 4
That is even broken in Labrador, so much work to do :(

irb(main):001:0> require 'labrador'
=> true
irb(main):002:0> [1,2,3].map + 2
=> [3, 4, 5]
irb(main):003:0> [1,2,3].map + 2 * 3
=> [7, 8, 9] *** Arrrgh
>
> We have to do:
>
>   ([1,2,3].map * 6).map + 4
>
> Not quite as bad for #map, as opposed to #every, being shorter, but it
> would still be nice to chain. Of course, to do that one must
> explicitly #to_a the final result per my original Enumerator example.

>
> One thing you might want to consider, Ruby 1.9+ returns an Enumerator
> for #map without a block, could pose some compatibility issues in the
> future.
That is a good thing, and thanks for pointing it out, looking for a
different name for #map now ;)
 Though, I have to admit I'm not quite sure what a #map based
> Enumerator is good for -- when you run #each on it, it acts like
> #map !!!
>
> T.
>
Cheers
Robert

-- 
You see things; and you say Why?
But I dream things that never were; and I say Why not?
-- George Bernard Shaw