# Pipe arguments (ruby q)

**URL:** <https://in-thread.sonic-pi.net/t/pipe-arguments-ruby-q/8810>\
**Category:** Support, Help & Resources\
**Created:** [April 29, 2024, 8:28am UTC](https://in-thread.sonic-pi.net/t/pipe-arguments-ruby-q/8810 "2024-04-29T08:28:41Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![jonny](https://avatars.discourse-cdn.com/v4/letter/j/47e85d/32.png) [@jonny](https://in-thread.sonic-pi.net/u/jonny)\
**Post date:** [April 29, 2024, 8:28am UTC](https://in-thread.sonic-pi.net/t/pipe-arguments-ruby-q/8810/1 "2024-04-29T08:28:41Z")

</div>

Hey all, not sure if anyone can shed any light here…

I was playing with some limited randomness.  
I’ve got a live loop running, randomly augmented with extra loop samples.

So as to avoid the main loop being delayed by sample playback and wait time, I’ve called the sample from within a thread via a method _within_ the live\_loop.

After some success with this looped oneshot nonsense I then tried to tinker to allow multiple voices. I’m sure there’s questionable logic (at many levels!)

One thing I’d like to do is additionally pipe any arguments that are provided as `*args`  
I’ve seen examples using .merge previously , and even some currying (anyone else think of Ruby Murray when seeing that method?! Just googled, never knew she was a she or a singer… I digress : )

```ruby
max_voices = 3
active_voices = 0

define :oneshot do |s, fx, *args|
  if active_voices < max_voices
    in_thread name: ("samples" + active_voices.to_s).to_sym do #can args be injected in here?!
      active_voices += 1
      t = sample_duration s
      puts s, fx
      sample s
      wait t
      active_voices -= 1
      stop
    end
  end
end

live_loop :l1 do
  fxlist = fx_names.to_a
#exc. record fx as not needed, & throws an error if selected as requires an argument
  fx = fxlist.reject {|fx| fx == :record}.choose 

  with_fx fx, reps: rand(1..4) do
    oneshot (sample_names :loop).choose , fx
  end
  
  with_fx :wobble, pulse_width: 0.1 do |wob| #reps kill_delay #, filter: 0
    density 1 do
      play :c
      # stop
      wait 2
    end
  end
end

```

Ideally additional arguments can be piped, initially just thread args, eg something like

` oneshot (sample_names :loop).choose , fx, delay: 1, sync: :l2`

I’ve worked out the logic to get to the (hash) elements within the (args) array

```ruby
args.each_with_index {|a,i| a.each_pair \  
{|h,v| "#{i.zero? ? ', ' : '' }#{h}: #{v}"}}`

```

but even if I assign this a variable I’m still not sure how to inject this.

* * *

Also I’ve now got some new random popping currently (using speakers as headphones AWOL) . which may require a lower attack or release or something to fix, on the fx/playback… any ideas on how to troubleshoot/fix this also most welcome!

---

<div class="post-metadata">

**Author:** ![emlyn](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/emlyn/32/1460_2.png) [@emlyn](https://in-thread.sonic-pi.net/u/emlyn)\
**Post date:** [April 29, 2024, 11:48am UTC](https://in-thread.sonic-pi.net/t/pipe-arguments-ruby-q/8810/2 "2024-04-29T11:48:02Z")

</div>

After fiddling around with it for a bit, I think this seems to do what you want. You don’t need the `*`, as the trailing args already seem to get collected into a hash (I don’t know Ruby well enough to understand exactly why…):

```ruby
max_voices = 3
active_voices = 0

define :oneshot do |s, fx, args|
  if active_voices < max_voices
    args[:name] = ("samples" + active_voices.to_s).to_sym
    puts args
    in_thread args do
      active_voices += 1
      t = sample_duration s
      puts s, fx
      sample s
      wait t
      active_voices -= 1
      stop
    end
  end
end

oneshot :loop_amen, :some_fx, sync: :l2, delay: 1

sleep 2

cue :l2

```

---

<div class="post-metadata">

**Author:** ![jonny](https://avatars.discourse-cdn.com/v4/letter/j/47e85d/32.png) [@jonny](https://in-thread.sonic-pi.net/u/jonny)\
**Post date:** [April 29, 2024, 5:28pm UTC](https://in-thread.sonic-pi.net/t/pipe-arguments-ruby-q/8810/3 "2024-04-29T17:28:59Z")

</div>

Thanks! This is so helpful 🙏🏻  
I first encountered `*args` when looking at optional arguments.  
So it seems in\_thread expects and requires just one hash for it’s arguments, and injecting the name into the args as you demonstrate is the way to do it. Thanks!

I tried with the _other_ param type ` **` and that works whils allowing for nil args. I _think_ the logic you mention is that `*` gets you an auto-array, whilst `** ` gets you a hash.

# 👍🏻
