I would like to add a method to the Array class, say Array#pop! which
is actually split!(-1). But then, I can think of a more general
problem: define a new function by composition of two or more
functions.
In Haskell, I can do something like
"Edgardo Hames" <ehames@gmail.com> schrieb im Newsbeitrag
news:478c16ae0408061209424c2032@mail.gmail.com...
Hi.
I would like to add a method to the Array class, say Array#pop! which
is actually split!(-1). But then, I can think of a more general
problem: define a new function by composition of two or more
functions.
In Haskell, I can do something like
f :: a -> b -> c
f x y = something
g::b -> c
g = f some_value
What is the Ruby equivalent of this?
Regards,
Ed
How about
class Array
def pop!() split!(-1) end
end
Note: pop! and split! are not functions but methods. So you always have an
implicit argument (named 'self' in Ruby). I think this does not lend easily
to chaining the way you seek.
Of course, for the general case you could do something like this:
module Kernel
private
def chain(name, *funcs)
eval "def #{name}(*a) #{funcs.map {|f| "#{f}("}}*a#{")" * funcs.size}
end"
end
end
def foo(x) "<#{x}>" end
=> nil
def bar(x) "[#{x}]" end
=> nil
chain :xxx, :foo, :bar
=> nil
xxx 100
=> "<[100]>"
Or a more functional approach:
module Kernel
private
def chain2(*funcs)
lambda {|*a| funcs.inject(a){|val, fun| send(fun, *val) } }
end
end
I imagined this. But, I thought you were going to surprise me with a
weird (or unimagined) way to use alias
Thanks,
Ed
···
On Sat, 7 Aug 2004 04:46:25 +0900, Robert Klemme <bob.news@gmx.net> wrote:
"Edgardo Hames" <ehames@gmail.com> schrieb im Newsbeitrag
news:478c16ae0408061209424c2032@mail.gmail.com...
>
> I would like to add a method to the Array class, say Array#pop! which
> is actually split!(-1). But then, I can think of a more general
> problem: define a new function by composition of two or more
> functions.
"Edgardo Hames" <ehames@gmail.com> schrieb im Newsbeitrag
news:478c16ae0408061209424c2032@mail.gmail.com...
I would like to add a method to the Array class, say Array#pop! which
is actually split!(-1). But then, I can think of a more general
problem: define a new function by composition of two or more
functions.
How about
class Array
def pop!() split!(-1) end
end
I imagined this. But, I thought you were going to surprise me with a
weird (or unimagined) way to use alias
Though this won't do what you want since there isn't a method split! for array.
I think what you actually want is something like
class Array
def pop!
slice!(-1, 1)
end
end
This discussion did give me an idea for a curry method, that let's you predefine the parameters for a method.
class Class
def curry(newmethod, oldmethod, stored_params)
send(:define_method, newmethod) do |*args|
x = stored_params
x += args if args
send(oldmethod, *x)
end
end
end
then you can define pop! with
class Array
curry(:pop!, :slice!, -1, 1)
end
then
x = [1,2,3]
p x.slice! #=> 3
p x #=> [1,2]
···
On Sat, 7 Aug 2004 04:46:25 +0900, Robert Klemme <bob.news@gmx.net> wrote:
"Edgardo Hames" <ehames@gmail.com> schrieb im Newsbeitrag
news:478c16ae0408061345100e8692@mail.gmail.com...
>
> "Edgardo Hames" <ehames@gmail.com> schrieb im Newsbeitrag
> news:478c16ae0408061209424c2032@mail.gmail.com...
> >
> > I would like to add a method to the Array class, say Array#pop! which
> > is actually split!(-1). But then, I can think of a more general
> > problem: define a new function by composition of two or more
> > functions.
>
> How about
>
> class Array
> def pop!() split!(-1) end
> end
I imagined this. But, I thought you were going to surprise me with a
weird (or unimagined) way to use alias
Not possible because of the argument.
Here's another solution - even more functional, although I still think this
looks a bit more elegant in functional languages:
def concat3(*fun)
lambda {|*a| fun.inject(a) {|val,f| f.call(*val)} }
end
foo = lambda {|x| "<#{x}>"}
=> #<Proc:0x1019fac0@(irb):17>
bar = lambda {|x| "[#{x}]"}
=> #<Proc:0x10194d38@(irb):18>
xx3 = concat3 bar, foo
=> #<Proc:0x101b7250@(irb):15>
xx3.call 100
=> "<[100]>"
xx3[ 100 ]
=> "<[100]>"
As you can see, there are plenty ways to do this. And you can even use Ruby
as a functional language, although I'd say best use is made of it if you use
it OO.
Regards
robert
···
On Sat, 7 Aug 2004 04:46:25 +0900, Robert Klemme <bob.news@gmx.net> wrote: