Devin Mullins said:
One could generalize that solution:
class Symbol
def to_proc
lambda { |a,*b| a.send(self,*b) }
end
Wow, I really like it! Why didn't I think of that?
You've unified my version with the usual definition,
resulting in the be-all and end-all of Symbol#to_proc.
This *so* needs to be put in the standard library.
class Symbol
def *(ary)
ary.inject {|a,b| a.send(self, b)}
end
Way cool! I actually like this one, and I'm not kidding.
Redefine Array#* to double-dispatch on symbols and this will
actually be usable. Think about it=E2=80=94
[1,2,3] * "+" means [1,2,3].join("+"),
so it makes sense for
[1,2,3] * :+ to mean [1,2,3].inject(&:+).
More intuitively, we think of =E2=80=98[*foo] * "bar"=E2=80=99 as joining
the elements of =E2=80=98foo=E2=80=99 by "bar". Analogously, we can thin=
k
of =E2=80=98[*foo] * :bar=E2=80=99 as joining, or more correctly *recudin=
g*,
the elements of =E2=80=98foo=E2=80=99 using :bar.
This strikes me as highly intuitive:
[1,2,3] * "+" #=3D> "1+2+3"
[1,2,3] * :+ #=3D> 1 + 2 + 3
As does this (though perhaps slightly less so):
[1,2,3] * "foo" #=3D> "1foo2foo3"
[1,2,3] * :foo #=3D> 1.foo(2).foo(3)"
[crazy APL stuff snipped]
Now, :+*[1,2,3], :+[1,2,3], and +[1,2,3] are all valid.
(Not that I actually use this libary; just came up with it
to make a point about Ruby to somebody.
)
That's cool; you really managed to take this to its extreme.
Of course, =E2=80=98:+[1,2,3]=E2=80=99 is too cryptic and =E2=80=98+[1,2,=
3]=E2=80=99 is
better written as =E2=80=98[1,2,3].sum=E2=80=99, but still.
(I would've overloaded /, but Ruby kept thinking I was
trying to construct a regular expression.)
Hmm, what would you have had that do?
And here's a vaguely neat extension of that idea:
class Symbol
def **(ary)
ary.inject { |a,b| a.send(self, *b) }
end
end
:gsub ** ["Hello!",
[/Hell/,"Good"]
[/o!/,"bye.]]
Talk about reducing duplication.
Wow... amazing. Of course, this
["Hello!", [/Hell/, "Good"], [/o!/, "bye."]] ** :gsub
is both longer and more cryptic than this,
"Hello!".gsub(/Hell/, "Good").gsub(/o!/, "bye.")
but still... the former has *no* duplication.
By the way, the above example suggests that it might be
useful to have String#gsub take multiple arguments:
class String
unless method_defined? :gsub1
alias :gsub1 :gsub
def gsub(*a)
(a.size =3D=3D 1 ? a.first : a.pairs).
inject(self) { |a, b| a.gsub1 *b }
end
end
end
module Enumerable
def pairs ; groups(2) end
def groups(n)
(a =3D entries).each_index { |i| a[i, n] =3D [a[i, n]] }
end
end
"Hello!".gsub(/Hell/ =3D> "Good", /o!/ =3D> "bye.") #=3D> "Goodbye."
Using a hash to visually pair each expression to its
replacement has the unfortunate side effect of effectively
randomizing the order of the substitutions, so you'll have
to use commas if order is significant:
"Hello!".gsub(/Hell/, "Good", /o!/, "bye.") #=3D> "Goodbye."
Anyway, thanks for sharing your cool inventions, Devin.
--=20
Daniel Brockman <
[email protected]>
So really, we all have to ask ourselves:
Am I waiting for RMS to do this? --TTN.