"Martin DeMello" <martindemello@gmail.com> writes:
(1..10).map &lambda {|i| i*2}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
David, do you want to allow (1..10).map(:*, 2) ?
···
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org
"Martin DeMello" <martindemello@gmail.com> writes:
(1..10).map &lambda {|i| i*2}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
David, do you want to allow (1..10).map(:*, 2) ?
--
Christian Neukirchen <chneukirchen@gmail.com> http://chneukirchen.org
Hi --
On Fri, 15 Dec 2006, Yukihiro Matsumoto wrote:
Hi,
In message "Re: map taking an argument (was: Re: join_with)" > on Thu, 14 Dec 2006 01:58:15 +0900, dblack@wobblini.net writes:
>There was an RCR a while back, rejected by Matz, that asked for:
>
> enum.map(:m)
>
>to be the same as:
>
> enum.map {|e| e.m }
>
>It looks like Ruby >= 1.9 has this:
>
> enum.map(&:m)
>
>which strikes me as the same thing, functionally, but visually noisier
>and semantically more obscure.
>
>I'm just wondering what the rationale is for rejecting the simple
>version and introducing the less simple one.(a) noisier form works not only for map, but also for every method
that take a block.(b) if we wanted to add same functionality for every iterator method,
we have to modify them all. besides that, some iterator methods
already take arguments that make less noisy form difficult.(c) ampersand would serve as visual clue, which tells you that symbol
works as some kind of block. it is difficult to tell what :m
means in less noisy form. that could be a method name that map
based on instead of each, or some other thing.Choose whichever you want.
I'll take (a) and (b)
I understand (c) too, though.
David
--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
I've settled on Enumerable#jmap in my personal code - it fits my
thinking, because I'm focusing on the map, and the join is secondary.
martin
On 12/7/06, Vincent Fourmond <vincent.fourmond@9online.fr> wrote:
I vote for this function, although the name, join_with, really isn't
telling what it's doing (it doesn't speak to me, unlike most ruby method
names).
Hi --
On Thu, 14 Dec 2006, Daniel Berger wrote:
ara.t.howard@noaa.gov wrote:
<snip>
given that this will work all over the place, it's doubtfull that it will be
more obsure than a special case for map, since people will use the idiom all
over the place.I doubt it. My feeling, based on the posts I've seen on the topic over
the last couple of years, is that most people just want it for map and
select.
I hope you're right. I dislike it not only for its line-noise
qualities (I know I can't be *too* squeamish about that), but also
because it seems like a stretch to characterize it as a conversion
from a Symbol to a Proc. Maybe I'll get used to it (or maybe other
people won't ![]()
David
--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
Hi --
i think that makes good sense considering ruby's pattern of not
auto-magically munge aruements: we all agree that it's a good thing
that this does not work"40" + 2
the e.map(:m) is exactly the equivalent of that: it says "by the
way, if you pass me a symbol object i'll auto-magically convert that
to a method call on the object.I don't see a similarity.
in both cases the arguments types changes the semantics of the method. in one
case a number is numged into a string. in the other a symbol is munged into a
method/proc. in both cases this behaviour is burried in the method and users
of the methods must know that passing certain classes of objects results in
different behaviour. consider this pattern applied to more methods that take
blocks but currently no arguments - can we always make the meaning the same?
"Munged" is a broad enough term that it probably covers both
I
don't think they're all that similar at a more granular level. Mind
you, I'm not fully in favor of map(:meth). I'm just not clear on why
the &: thing got in and the argument thing didn't.
It's not a conversion to a method; you couldn't replace the symbol with a
method object.harp: > cat a.rb
class String
def up(*a) upcase end
ends = 'forty-two'
p( [s].map(&:up) )
p( [s].map(&s.method(:up)) )harp: > ruby19 a.rb
["FORTY-TWO"]
I was talking about the old RCR, not the new thing. Interesting that
the conversion does indeed seem to be symbol to method to proc, not
symbol to proc.
It's just a decision to have the argument have that meaning.
It may even be more circuitous, in a sense, than converting 2 to a string,
but I don't think it's the same at all.it's not __just__ having the argument have a meaning, it's having a particular
class of object specify block auto-creation when it was originally nil. the
indirection isn't extensible to other methods, transparent, or orthongonal.
for instance, what does this do?enum.map(:upcase){|e| e.downcase} # noop
it could throw an error - but why should it?
Because methods don't take two blocks. The proposal, as I recall, was
that :upcase would trigger the creation of a block -- *the* block.
we could simply have rule that the two blocks, the implied and the
actual, are always run in a given order, say left to right. once
we're there, we take the step that multiple args be given and that
they too will be called left to right...enum.map(:upcase, :downcase){|e| e.upcase} # not noop
now, the impl of map is very useful and yet the code is more complex, next we
can tackle #each, then we can move on to each and every method that takes a
block but takes no args. each one can have similar, or differnt behaviour
based on extra symbol args. blocks that take multiple args will really
complicate the rules. then we can doccument them....yuk! this is what's known as code acretion and it's a __bad_thing__.
__or__ we can write Symbol#to_proc __once__. doccument it __once__, and every
single method in ruby, stdlibs, and user code can now leverage this
functionality to compactly specified a block of {|elem| elem.send :meth} as
simply &:meth.you can't really think the former is a better course of action do you?
I don't follow the reasoning here. Of course you could add arbitrary
numbers of arguments and blocks to anything and make it unwieldy.
That wasn't what was proposed, though; it was just giving iterators
that don't take arguments an argument, as a concise way to create a
block (like &: but without the &).
given that this will work all over the place, it's doubtfull that it
will be more obsure than a special case for map, since people will
use the idiom all over the place.Maybe that's what I'm afraid of. I find it obscure and ugly.
well, that's hard to argue about.
still, there are alot of ugly syntax
elements in ruby likeclass << self
and
@@ugly
and
*list
and
self.a = :value
still. we can just call these 'beauty marks' can't we?
I only see one ugly one there
In any case, I don't think the
answer is to shrug and say, "Well, there's already a bit of line noise
here and there, so let's throw in the towel and go all the way." So
much of what's cool in Ruby is cool because of the individual
attention to things -- the hand-crafting, so to speak. This one just
seems like not one of the big successes, stylistically or
semantically, to me.
David
On Thu, 14 Dec 2006, ara.t.howard@noaa.gov wrote:
On Thu, 14 Dec 2006 dblack@wobblini.net wrote:
--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
Does the version currently in Ruby 1.9 support arguments?
James Edward Gray II
On Dec 13, 2006, at 3:56 PM, Christian Neukirchen wrote:
"Martin DeMello" <martindemello@gmail.com> writes:
(1..10).map &lambda {|i| i*2}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
David, do you want to allow (1..10).map(:*, 2) ?
Hi --
"Martin DeMello" <martindemello@gmail.com> writes:
(1..10).map &lambda {|i| i*2}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
David, do you want to allow (1..10).map(:*, 2) ?
I don't particularly want to allow map(:anything)
I was just
somewhat surprised to see the idea return in a slightly new form,
since Matz had rejected it a while ago.
If I were designing map(:name), I don't think I'd want it to take
arguments. But I have no technical grounds for saying so, only
aesthetic ones.
David
On Thu, 14 Dec 2006, Christian Neukirchen wrote:
--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
The I'd spent at least three or four more characters - your current naming lets me think of some javaism. ![]()
robert
On 07.12.2006 12:56, Martin DeMello wrote:
On 12/7/06, Vincent Fourmond <vincent.fourmond@9online.fr> wrote:
I vote for this function, although the name, join_with, really isn't
telling what it's doing (it doesn't speak to me, unlike most ruby method
names).I've settled on Enumerable#jmap in my personal code - it fits my
thinking, because I'm focusing on the map, and the join is secondary.
Hi --
On Thu, 14 Dec 2006, James Edward Gray II wrote:
On Dec 13, 2006, at 3:56 PM, Christian Neukirchen wrote:
"Martin DeMello" <martindemello@gmail.com> writes:
(1..10).map &lambda {|i| i*2}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
David, do you want to allow (1..10).map(:*, 2) ?
Does the version currently in Ruby 1.9 support arguments?
I don't think so. I'm actually not sure where they'd go, since &:meth
is the block and not an argument.
David
--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
you confound me david! ![]()
if you like 'e.map :m' how can you __not__ like
harp:~ > cat a.rb
class Array
def map *a, &b
m, *a = *a
super &(b || lambda{|o| o.send m, *a})
end
end
prefixes = %w( foo-bar bar-foo ).map :, /^\w+/
p prefixes
harp:~ > ruby a.rb
["foo", "bar"]
?
-a
On Thu, 14 Dec 2006 dblack@wobblini.net wrote:
Hi --
On Thu, 14 Dec 2006, Christian Neukirchen wrote:
"Martin DeMello" <martindemello@gmail.com> writes:
(1..10).map &lambda {|i| i*2}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
David, do you want to allow (1..10).map(:*, 2) ?
I don't particularly want to allow map(:anything)
I was just
somewhat surprised to see the idea return in a slightly new form,
since Matz had rejected it a while ago.If I were designing map(:name), I don't think I'd want it to take
arguments. But I have no technical grounds for saying so, only
aesthetic ones.
--
if you find yourself slandering anybody, first imagine that your mouth is
filled with excrement. it will break you of the habit quickly enough. - the
dalai lama
Hi --
Hi --
"Martin DeMello" <martindemello@gmail.com> writes:
(1..10).map &lambda {|i| i*2}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
David, do you want to allow (1..10).map(:*, 2) ?
I don't particularly want to allow map(:anything)
I was just
somewhat surprised to see the idea return in a slightly new form,
since Matz had rejected it a while ago.If I were designing map(:name), I don't think I'd want it to take
arguments. But I have no technical grounds for saying so, only
aesthetic ones.you confound me david!
if you like 'e.map :m' how can you __not__ like
harp:~ > cat a.rb
class Array
def map *a, &b
m, *a = *a
super &(b || lambda{|o| o.send m, *a})
end
endprefixes = %w( foo-bar bar-foo ).map :, /^\w+/
p prefixesharp:~ > ruby a.rb
["foo", "bar"]?
I didn't say I liked e.map(:m); I said I wondered why it was rejected
and now the same functionality has returned in a noisier form ![]()
But the broader answer is: because I don't think about Ruby design
questions as a matter of one thing leading inexorably to another.
Liking e.map(:m) would not imply liking anything else.
I suppose I've answered my own question, in a sense: Matz's dislike of
map(:m) does not imply disliking anything else, including map &:m.
That principle is so important. I'm even willing to pay the price of
&:m to see it upheld ![]()
David
On Thu, 14 Dec 2006, ara.t.howard@noaa.gov wrote:
On Thu, 14 Dec 2006 dblack@wobblini.net wrote:
On Thu, 14 Dec 2006, Christian Neukirchen wrote:
--
Q. What's a good holiday present for the serious Rails developer?
A. RUBY FOR RAILS by David A. Black (http://www.manning.com/black\)
aka The Ruby book for Rails developers!
Q. Where can I get Ruby/Rails on-site training, consulting, coaching?
A. Ruby Power and Light, LLC (http://www.rubypal.com)
A few days ago, I modified Dr. Nic's MapByMethod gem (locally) to attempt to handle arguments. The results were interesting.
Scroll down for some examples.
On Dec 13, 2006, at 2:40 PM, dblack@wobblini.net wrote:
Hi --
On Thu, 14 Dec 2006, James Edward Gray II wrote:
On Dec 13, 2006, at 3:56 PM, Christian Neukirchen wrote:
"Martin DeMello" <martindemello@gmail.com> writes:
(1..10).map &lambda {|i| i*2}
=> [2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
David, do you want to allow (1..10).map(:*, 2) ?
Does the version currently in Ruby 1.9 support arguments?
I don't think so. I'm actually not sure where they'd go, since &:meth
is the block and not an argument.David
#
# --copy into irb--
#
module FindByMethod
def method_missing method, *args, &block
begin
method_missing_handler method, *args, &block
rescue
super
end
end
FIND_BY_REGEX = /^(all|any|collect|detect|find_all|find|first_match|grep|group_by|map|none|partition|reject|select|sort_by)_?(by|where)?_([\w_]+\??)$/
QUERY_ITERATORS = ["all","any","none"]
def method_missing_handler method, *args, &block
unless method.to_s.match FIND_BY_REGEX
raise NoMethodError
end
iterator = $1
selector = $2
callmethod = $3
iterator += "?" if QUERY_ITERATORS.include? iterator
self.send(iterator) do |item|
if selector == "where"
# Arguments used in boolean comparison
if args.length == 1
args.first == item.send(callmethod)
else
args.include? item.send(callmethod)
end
else
# Arguments fall through
item.send(callmethod,*args)
end
end
end
end
Array.send :include, FindByMethod
#
# ---stop---
#
#
# Examples!
#
[1,2,3].map_by_succ
# => [2, 3, 4]
# -- equivalent to [1,2,3].map { |x| x.succ }
[1,2,nil].select_by_nil?
# => [nil]
# -- equivalent to [1,2,nil].select { |x| x.nil? }
#
# Now lets try some arguments.
# (Normally they're passed right to the method.)
#
[2,4,6].map_by_div(2)
# => [1, 2, 3]
["1","one"].select_by_match(/\d/)
# => ["1"]
#
# If you've gotten ahead of me, you're probably wondering
# how you would pull off a rails-like magic finder:
#
# users.find_by_name("charlie")
#
# I struggled with that one for a long time, before settling
# on using 'find_where' instead of 'find_by' where you need
# it to equal an argument rather than pass through an argument.
#
[1,2,'a'].select_where_class(Fixnum)
# => [1, 2]
# -- equivalent to [1,2,'a'].select { |x| x.class == Fixnum }
#
# You can use most enumerable methods as well.
#
[1,2,3].partition_where_to_f(3.0)
# => [[3], [1, 2]]
#
# Some special cases though are .any?, .none?, and .all?
#
#They work, but you need to omit the question mark or ruby
# throws up all over her prom dress.
#
[1,2,3].any_by_nil?
# => false
#
# Keep in mind that it's easy to mix up 'where' and 'by'.
# Compare these two identical sounding method calls.
#
[1,2,'a'].select_where_kind_of?(Fixnum)
[1,2,'a'].select_by_kind_of?(Fixnum)
# Can you guess which works and which crashes?
#
# _by_ works as it translates into:
# x.kind_of?(Fixnum)
#
#_where_ raises an exception because it becomes gibberish:
# x.kind_of? == Fixnum
#
# I had to run it to figure out the difference too. There's something
# seriously wrong with the words I chose to distinguish between
# passing an argument from equaling an argument.
#
# - Mike
It hasn't really returned - it's just a small "hack" being officially
blessed. Indeed, it's almost exactly like adding to_a to Enumerable
makes *(1..10) work.
martin
On 12/14/06, dblack@wobblini.net <dblack@wobblini.net> wrote:
On Thu, 14 Dec 2006, ara.t.howard@noaa.gov wrote:
I didn't say I liked e.map(:m); I said I wondered why it was rejected
and now the same functionality has returned in a noisier form