From: "nevans (Nicholas Evans)" Date: 2022-05-10T18:02:48+00:00 Subject: [ruby-core:108504] [Ruby master Feature#18690] Allow `Kernel#then` to take arguments Issue #18690 has been updated by nevans (Nicholas Evans). For your scenarios, as written, I agree with Benoit's #note-2 suggestions. ;) I also agree that core/stdlib `#then` should only ever yield a single value to its block. *However*, it's worth noting that multi-parameter blocks will automatically deconstruct a single array arg. E.g: ``` irb irb(main):001:0> %i[hello world this_is_the_third].then {|x, y, z| puts "first: #{x}"; puts "second: #{y}"; puts "third: #{z}"; [x.to_s, y.to_s.upcase, z.to_s[-5..]] } first: hello second: world third: this_is_the_third => ["hello", "WORLD", "third"] irb(main):023:0> def foo(x) = puts "foo(%p)" % x => :foo irb(main):024:0> def bar(y) = puts "bar(%p)" % y => :bar irb(main):025:0> def baz(x) = puts "baz(%p)" % x => :baz irb(main):026:0> def qux(x, y, z) = puts("qux(%p, %p, %p)" % [x, y, z]).then { :done_qux } => :qux irb(main):027:0> honyarara, fugafugafuga, hogehogehoge = :honyarara, :fugafugafuga, :hogehogehoge => [:honyarara, :fugafugafuga, :hogehogehoge] irb(main):028:1* [honyarara, fugafugafuga, hogehogehoge].then {|x,y,z| # blocks automatically destructure array args irb(main):029:1* foo(x); bar(y); baz(x); qux(x, y, z) irb(main):030:0> } foo(:honyarara) bar(:fugafugafuga) baz(:honyarara) qux(:honyarara, :fugafugafuga, :hogehogehoge) => :done_qux irb(main):031:0> p = proc {|x,y,z| foo(x); bar(y); baz(x); qux(x, y, z) } # procs handle args like blocks => # irb(main):032:0> [honyarara, fugafugafuga, hogehogehoge].then(&p) foo(:honyarara) bar(:fugafugafuga) baz(:honyarara) qux(:honyarara, :fugafugafuga, :hogehogehoge) => :done_qux irb(main):033:0> lunary = -> a { x,y,z = a; foo(x); bar(y); baz(x); qux(x, y, z) } # lambdas handle args like methods => # irb(main):034:0> [honyarara, fugafugafuga, hogehogehoge].then(&lunary) foo(:honyarara) bar(:fugafugafuga) baz(:honyarara) qux(:honyarara, :fugafugafuga, :hogehogehoge) => :done_qux irb(main):035:0> l3args = -> x, y, z { foo(x); bar(y); baz(x); qux(x, y, z) } => # irb(main):036:0> [honyarara, fugafugafuga, hogehogehoge].then{l3args.(*_1)} foo(:honyarara) bar(:fugafugafuga) baz(:honyarara) qux(:honyarara, :fugafugafuga, :hogehogehoge) => :done_qux irb(main):037:0> lwrapped = -> ((x, y, z)) { foo(x); bar(y); baz(x); qux(x, y, z) } => # irb(main):038:0> [honyarara, fugafugafuga, hogehogehoge].then(&lwrapped) foo(:honyarara) bar(:fugafugafuga) baz(:honyarara) qux(:honyarara, :fugafugafuga, :hogehogehoge) => :done_qux ``` I most commonly do this when I'm iteratively constructing a one-shot data-munging query in irb/pry. Pipeline segments can output arrays which can be deconstructed by the next segment into multiple args. IMO, it's a great technique for the REPL, but positional parameters can get unwieldy fast. Except for when it's *very* simple and self-documenting, I prefer to refactor to something that's easier to read before committing or merging. ---------------------------------------- Feature #18690: Allow `Kernel#then` to take arguments https://bugs.ruby-lang.org/issues/18690#change-97548 * Author: sawa (Tsuyoshi Sawada) * Status: Open * Priority: Normal ---------------------------------------- `Kernel#then` passes the receiver to the block as its first positional block parameter. ```ruby 1.5.then{|x| Math.atan(x)} ``` I would like to propose to let `then` take arguments, which would be passed to the block as the other block parameters. ```ruby 3.then(4){|x, y| Math.hypot(x, y)} ``` There are two uses. First, to separate bulky or repeated parameters from the routine. Instead of writing: ```ruby honyarara.then{|x| foo(x) bar(fugafugafuga) baz(hogehogehoge) qux(x, fugafugafuga, hogehogehoge) } ``` we can then write: ```ruby honyarara.then(fugafugafuga, hogehogehoge){|x, y, z| foo(x) bar(y) baz(x) qux(x, y, z) } ``` Second, to use a proc with multiple parameters when, for some reason, you do not want to define a method to do it: ```ruby p = ->(x, y, z){ foo(x) bar(y) baz(x) qux(x, y, z) } honyarara.then(fugafugafuga, hogehogehoge, &p) ``` -- https://bugs.ruby-lang.org/ Unsubscribe: