How to mix required argument and optional arguments in ruby?

后端 未结 2 1128
难免孤独
难免孤独 2021-01-14 19:43

I am working on ruby, and the following is my code snippet. I tried mixing required arguments and option arguments. But it gives me an error:

def my_method(a         


        
2条回答
  •  独厮守ぢ
    2021-01-14 19:48

    The code you have works just fine in any recent version of Ruby. It won't work in really old versions of Ruby, though, since required positional arguments after splat arguments were only introduced in Ruby 1.9.0.

    A pseudo-regex for parameter lists in Ruby is something like this:

    mand* opt* splat? mand* (mand_kw | opt_kw)* kwsplat? block?
    

    Here's an example:

    def foo(m1, m2, o1=:o1, o2=:o2, *splat, m3, m4, 
              ok1: :ok1, mk1:, mk2:, ok2: :ok2, **ksplat, &blk)
      Hash[local_variables.map {|var| [var, eval(var.to_s)] }]
    end
    
    method(:foo).arity
    # => -5
    
    method(:foo).parameters
    # => [[:req, :m1], [:req, :m2], [:opt, :o1], [:opt, :o2], [:rest, :splat], 
    #     [:req, :m3], [:req, :m4], [:keyreq, :mk1], [:keyreq, :mk2], 
    #     [:key, :ok1], [:key, :ok2], [:keyrest, :ksplat], [:block, :blk]]
    
    foo(1, 2, 3, 4)
    # ArgumentError: missing keywords: mk1, mk2
    
    foo(1, 2, 3, mk1: 4, mk2: 5)
    # ArgumentError: wrong number of arguments (3 for 4+)
    
    foo(1, 2, 3, 4, mk1: 5, mk2: 6)
    # => { m1: 1, m2: 2, o1: :o1, o2: :o2, splat: [], m3: 3, m4: 4, 
    #      ok1: :ok1, mk1: 5, mk2: 6, ok2: :ok2, ksplat: {}, 
    #      blk: nil }
    
    foo(1, 2, 3, 4, 5, mk1: 6, mk2: 7)
    # => { m1: 1, m2: 2, o1: 3, o2: :o2, splat: [], m3: 4, m4: 5, 
    #      ok1: :ok1, mk1: 6, mk2: 7, ok2: :ok2, ksplat: {}, 
    #      blk: nil }
    
    foo(1, 2, 3, 4, 5, 6, mk1: 7, mk2: 8)
    # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [], m3: 5, m4: 6, 
    #      ok1: :ok1, mk1: 7, mk2: 8, ok2: :ok2, ksplat: {}, 
    #      blk: nil }
    
    foo(1, 2, 3, 4, 5, 6, 7, mk1: 8, mk2: 9)
    # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5], m3: 6, m4: 7, 
    #      ok1: :ok1, mk1: 8, mk2: 9, ok2: :ok2, ksplat: {}, 
    #      blk: nil }
    
    foo(1, 2, 3, 4, 5, 6, 7, 8, mk1: 9, mk2: 10)
    # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
    #      ok1: :ok1, mk1: 9, mk2: 10, ok2: :ok2, ksplat: {}, 
    #      blk: nil }
    
    foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11)
    # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
    #      ok1: 9, mk1: 10, mk2: 11, ok2: :ok2, ksplat: {}, 
    #      blk: nil }
    
    foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12)
    # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
    #      ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {}, 
    #      blk: nil }
    
    foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12, k3: 13)
    # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
    #      ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {k3: 13}, 
    #      blk: nil }
    
    foo(1, 2, 3, 4, 5, 6, 7, 8, ok1: 9, mk1: 10, mk2: 11, ok2: 12, k3: 13, k4: 14)
    # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
    #      ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {k3: 13, k4: 14}, 
    #      blk: nil }
    
    foo(1, 2, 3, 4, 5, 6, 7, 8, 
          ok1: 9, ok2: 10, mk1: 11, mk2: 12, k3: 13, k4: 14) do 15 end
    # => { m1: 1, m2: 2, o1: 3, o2: 4, splat: [5, 6], m3: 7, m4: 8, 
    #      ok1: 9, mk1: 10, mk2: 11, ok2: 12, ksplat: {k3: 13, k4: 14}, 
    #      blk: # }
    

提交回复
热议问题