简体   繁体   中英

In Ruby, how can you pass more than one hash to a method, without parentheses?

In Ruby, how can one pass more than one hash to a method, without parentheses?

For example

def abc x,y
end

abc {4,5},{6,4} <-- syntax error, unexpected ',', expecting '}'

Mu points out that you can pass multiple hashes without parentheses, if you pass them in as non-literals ie as variables.

But other than that, so, for literal hashes,

You do(need parentheses to pass multiple literal hashes), unless you are passing keyword arguments.. You can pass multiple keyword arguments without parentheses.

a keyword argument would be when the parameters of the method include a colon like eg def blah x:, y: then you can call with blah y:2,x:3 . Sometimes you have to look at the parameter(s) to see if an argument is a keyword argument, eg if you have a method called with abc x:3 then that might be def abc x: in which case you called it with a keyword argument. Or it might be def abc x in which case you called it with a hash, omitting the {}.

When I say keyword argument, I don't mean a hash.. and vice versa, when I say hash I mean not a keyword argument.

When a call is without parentheses, you can only pass one hash and that hash has to be the last argument. And you can skip the {} around it.

note- I'm no expert, but as to a related question of whether a keyword argument is a type of hash, from what I understand, as of writing, pre ruby 3, they are, but there is a proposal for ruby 3 to have 'real' keyword arguments that are distinct from hashes https://bugs.ruby-lang.org/issues/14183

a keyword argument can't be multi-valued.

also, a hash can be automatically converted to a keyword argument. (eg if a method is defined with a parameter that is a keyword argument, you can pass a hash in eg {x:"a"} , that x being a symbol, and that hash will be converted to a keyword argument x:"a" (that x being a parameter name).

I'll add a point regarding blocks and parentheses, because a block done with {} does look a little bit like a hash though is not a hash. And a block can have some influence on whether parentheses are needed.

If you see abc {} , that {} is a block not a hash, and blocks don't count as an argument. Hence that call works for def abc but not for def abc x where one would get an error related to number of arguments passed.

even when passing a block after some other arguments, there should be no comma before the block, and if a block done with {} follows some arguments, you need parentheses, but if a block done with do .. end follows some arguments, you don't need parentheses

it is suggested that one use parentheses when one has multiple arguments, unless it's a DSL(domain specific language). Do you leave parentheses in or out in Ruby?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM