title: Ruby - providing multiple lambda or proc arguments to a function?
body: <p>I've implemented a rudimentary extension on <code>Hash</code> with delegation via the <code>forwardable</code> module, in the following source code (public domain here)</p>
  <pre class="lang-rb prettyprint-override"><code>module OptionsConstants
    THIS = lambda { |a| a.itself }
  end
  
  
  require('forwardable')
  
  class AssocHash
  
    extend(Forwardable)
    include(Enumerable)
    def_delegators(:@table,
                   :[], :delete, :each, :keys, :values,
                   :length, :empty?,
                   :include?, :has_key?, :key?, :member?
                  )
  
    def self.table_default(whence)
      return lambda { |hash, key| raise(&quot;Found no key #{key} in #{whence.class} #{whence.object_id}&quot;) }
    end
  
    def initialize(&amp;keytest)
      @table = Hash.new(&amp;self.class.table_default(self))
      @keytest = ( keytest || OptionsConstants::THIS )
    end
    
  
    def add(obj, overwrite = false)
      usekey=key(obj)
      if @table.member?(usekey) 
        if (obj == @table[usekey])
          return obj
        elsif ! overwrite
          raise(&quot;An object is already registered for key #{usekey} in #{self.class} #{self}&quot;)
        end
      end
      @table[usekey]=obj
      return obj
    end
  
    def get(key)
      return @table[key]
    end
  
    def key(obj)
      @keytest.call(obj)
    end
  
  end
  </code></pre>
  <p>I'm still studying the syntax and semantics of the Ruby language. I think I've read a little about how <code>&amp;</code> might be handled in method argument lists, in the <a href="https://ruby-doc.org/core-2.6/Proc.html" rel="nofollow noreferrer">documentation for the <code>Proc</code> class in Ruby 2.6</a>. I'm not sure if I'm entirely clear about how this <code>&amp;procarg</code> syntax may operate, however. Perhaps it's nothing like a pointer in C?</p>
  <p>For implementing the <code>AsssocHash</code> class, I'd like to be able to pass two lambda objects to the <code>initialize</code> method, ideally with the second being optional, such that the second lambda object (or general proc) would be then used to provide a 'default' proc for the encapsulated hash <code>@table</code>. It would need to be provided as a <code>proc</code> to the <code>Hash</code> initializer. Subsequently, the <code>default</code> proc could then be provided from any calling API, in addition to the <code>@keytest</code> proc used directly in <code>AssocHash</code>.</p>
  <p>While working on the API for this, locally, it seemed that there may be some limitations entailed when using a <code>&amp;procarg</code> syntax?</p>
  <ul>
  <li>Cannot use two <code>&amp;procarg</code> in a method signature?</li>
  <li>Cannot use any arg after a <code>&amp;procarg</code> in a method signature?</li>
  <li>Does not provide a conventional required parameter, in an argument list?</li>
  </ul>
  <p>Presently, I may only be able to guess as to how <code>&amp;</code> might be used when passing any  object/lambda/proc to another method. While it may have &quot;Just worked&quot; to add <code>&amp;</code> to the expression for providing a default proc for the <code>Hash</code> initializer in the present implementation, in all candor I'm not certain as to why it was needed there, or how it affects what the <code>Hash</code> initializer receives. This might seem tangential to the question of how to provide any two proc expressions to the top-level initializer, in this code?</p>
  <p>I'm not certain if it's the most accurate terminology, to refer to it as a <code>&amp;procarg</code>. To my own albeit limited understanding of this aspect of Ruby syntax, the <code>&amp;</code> syntax seems to be required for the parameter that provides the value of <code>@keytest</code> to the initializer for <code>AssocHash</code>, such that the <code>@keytest</code> can then be used later in the expression, <code>@keytest.call</code></p>
  <p>Is there some way to provide a second proc to the initializer method, such that then could be used as a proc default for the <code>Hash</code> initializer?</p>
  <p>I'll try out a few more iterations on the syntax, here. I'm afraid there may not seem to be a lot of documentation around, about this <code>&amp;</code> qualifier in Ruby method signatures. I'm sure that it's thoroughly documented in the source code, however.</p>
  <p><strong>Update</strong></p>
  <p>Perhaps <code>&amp;</code> may not be required for passing a lambda or proc to a method?</p>
  <p>I believe that the following code may serve towards addressing the question</p>
  <pre class="lang-rb prettyprint-override"><code>module TestConstants
    NOKEY = lambda { |h,k| return &quot;No key: #{k}&quot; }
  end
  
  class Test
    def mkhash(fn = TestConstants::NOKEY) 
      Hash.new(&amp;fn)
    end
  end
  
  </code></pre>
  <p>subsequently, under irb:</p>
  <pre class="lang-rb prettyprint-override"><code>irb(main)&gt; t = Test.new
  =&gt; #&lt;Test:0x0000557c6fe2e460&gt;
  
  irb(main)&gt; h = t.mkhash
  =&gt; {}
  
  irb(main)&gt; h[:a]
  =&gt; &quot;No key: a&quot;
  
  irb(main)&gt; h = t.mkhash(lambda { |h,k| return &quot;Not found: #{k}&quot; })
  =&gt; {}
  
  irb(main)&gt; h[:b]
  =&gt; &quot;Not found: b&quot;
  </code></pre>
  <p>If it's possible to pass a lambda or proc to a method without denoting the parameter for it with <code>&amp;</code>, then the earlier <code>AssocHash</code> code can probably be updated as to how each lambda value will be passed in to the method.</p>
  <p>Perhaps that would be independent to how each lambda would then be stored within any instance variables and/or passed to the <code>Hash</code> constructor.</p>
  <p>At least, it might serve towards addressing a question of how to revise that single class. This <code>&amp;</code> qualifier is certainly an interesting bit of syntax, imo.</p>