From: Trans Date: 2008-04-27T05:14:51+09:00 Subject: Re: PartialInvocation sample On Apr 26, 2:42 pm, Guoliang Cao wrote: > 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] > -- > Posted viahttp://www.ruby-forum.com/. 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.