PartialInvocation sample

G

Guoliang Cao

Hi,

I created a partial invocation example below, which I think can be
useful in many cases. Since ruby 1.9 introduced curry as a syntax suger,
perhaps a generic and consistent partial invocation can be given a
thought.

# A partial invocation example
#
# Define a dummy object @@_ and define a kernel method _ to return that
object
# Modify method_missing in Object to treat method whose name ends with
'_' as a partial invocation
#
# Partial invocation is like obj.do_this_ a, _, c
#
# Benefit: intuitive partial invocation, can work with IDE's
auto-completion.
# Issue: people can use xxx_ as a real method name, which causes
confusion


class A
def do_this a, b, *c
puts "========== do_this: ", a, b, c
end

def self.do_that a, b, *c
puts "========== do_that: ", a, b, c
end
end

A.new.do_this 1, 2, 3, 4
A.do_that 1, 2, 3, 4

module Kernel
@@_ = Object.new
def _
@@_
end
end

class Object
alias method_missing_old method_missing

def method_missing method, *args, &block
if method.to_s[-1,1] == '_'
lambda{|*a|
new_args = []
args.each_with_index do |arg, i|
if arg === _
if i < args.length - 1
new_args.push a.shift
else
new_args.push *a
end
else
new_args.push arg
end
end
new_method = method.to_s.chomp '_'
send new_method, *new_args, &block
}
else
method_missing_old method, *args, &block
end
end
end

A.new.do_this_(1, _, 3, 4)[2]
A.do_that_(1, _, 3, 4)[2]

A.new.do_this_(_, _, 3, 4)[1, 2]
A.do_that_(_, _, 3, 4)[1, 2]

A.new.do_this_(1, 2, 3, 4)[]
A.do_that_(1, 2, 3, 4)[]

do_this_ = A.new.do_this_(1, 2, _)
do_this_[3]
do_this_[3, 4]
 
T

Trans

Hi,

I created a partial invocation example below, which I think can be
useful in many cases. Since ruby 1.9 introduced curry as a syntax suger,
perhaps a generic and consistent partial invocation can be given a
thought.

# A partial invocation example
#
# Define a dummy object @@_ and define a kernel method _ to return that
object
# Modify method_missing in Object to treat method whose name ends with
'_' as a partial invocation
#
# Partial invocation is like obj.do_this_ a, _, c
#
# Benefit: intuitive partial invocation, can work with IDE's
auto-completion.
# Issue: people can use xxx_ as a real method name, which causes
confusion

class A
def do_this a, b, *c
puts "========== do_this: ", a, b, c
end

def self.do_that a, b, *c
puts "========== do_that: ", a, b, c
end
end

A.new.do_this 1, 2, 3, 4
A.do_that 1, 2, 3, 4

module Kernel
@@_ = Object.new
def _
@@_
end
end

class Object
alias method_missing_old method_missing

def method_missing method, *args, &block
if method.to_s[-1,1] == '_'
lambda{|*a|
new_args = []
args.each_with_index do |arg, i|
if arg === _
if i < args.length - 1
new_args.push a.shift
else
new_args.push *a
end
else
new_args.push arg
end
end
new_method = method.to_s.chomp '_'
send new_method, *new_args, &block
}
else
method_missing_old method, *args, &block
end
end
end

A.new.do_this_(1, _, 3, 4)[2]
A.do_that_(1, _, 3, 4)[2]

A.new.do_this_(_, _, 3, 4)[1, 2]
A.do_that_(_, _, 3, 4)[1, 2]

A.new.do_this_(1, 2, 3, 4)[]
A.do_that_(1, 2, 3, 4)[]

do_this_ = A.new.do_this_(1, 2, _)
do_this_[3]
do_this_[3, 4]

Hi,

#_ is sort off limits because IRB uses it. However, #__ is usable, and
that is what Facets' library uses.

While the notation is nice, I'm not sure is necessary. If #curry is
extended to take slot-order as arguments, then curry itself can be
used. Eg.

aproc = Proc.new{ |a,b| a ** b }

aproc.curry => lambda{ |a| lambda{ |b| a ** b }}

aproc.curry(1) => lambda{ |b| lambda{ |a| a ** b }}

More complex...

aproc = Proc.new{ |a,b,c,d| ...}

aproc.curry(3,1,0) => lambda{ |d| lambda{ |b| lambda{ |a| lambda{ |
c|...

Note, that last slot (2) is implied and need not be specified in the
arguments.

T.
 
G

Guoliang Cao

Trans said:
Hi,

#_ is sort off limits because IRB uses it. However, #__ is usable, and
that is what Facets' library uses.

I'm not familiar with how _ is used in IRB. Can you please explain a bit
more?
While the notation is nice, I'm not sure is necessary. If #curry is
extended to take slot-order as arguments, then curry itself can be
used. Eg.

aproc = Proc.new{ |a,b| a ** b }

aproc.curry => lambda{ |a| lambda{ |b| a ** b }}

aproc.curry(1) => lambda{ |b| lambda{ |a| a ** b }}

More complex...

aproc = Proc.new{ |a,b,c,d| ...}

aproc.curry(3,1,0) => lambda{ |d| lambda{ |b| lambda{ |a| lambda{ |
c|...

Note, that last slot (2) is implied and need not be specified in the
arguments.

T.

I agree curry can be made more generic. It'll be even better if we can
have partial invocation on method calls. I think most of the time procs
are local to a method and we can substitute known values into proc body
without currying. However partial method invocation can be very useful
to reduce entering same literal values.
 
A

Arlen Cuss

[Note: parts of this message were removed to make it a legal post.]

Hi,

I'm not familiar with how _ is used in IRB. Can you please explain a bit
more?


_ is the last returned value:

$ irb
Arlen
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,206
Messages
2,571,068
Members
47,674
Latest member
scazeho

Latest Threads

Top