At Surface,
Ruby appears to be quite similar to other object orieinted languages like Java,Php,C etc.
but, things get bit weird when we start to bump into blocks.
for example, this works
(0...8).max()
=> 7
but this doesn’t
(0...8).map(puts "hello world")
hello world
ArgumentError: wrong number of arguments(1 for 0)
Apprantly, map method doesn’t take arguments but takes blocks, so passing replacing () with {} fix the error.
(0...8).map{puts "hello world"}
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
=> [nil, nil, nil, nil, nil, nil, nil, nil]
And then, there are some methods should take both — blocks & arguments
8.downto(1){puts "hello world"}
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
=> 8
The problem I have is the confusion on if I should be using () , {} or both on given method. On what basis it gets decided?
- Is it fixed on per method basis & I just to have remember what the method takes(Blocks or params)?
- Or is there any other logical reasoning on basis of which it gets decided, if the method takes blocks
{}or params()?
Please help me understand
Parenthesis after method calls are actually optional.
(0...8).map{puts "hello world"}is equivalent to(0...8).map() {puts "hello world"}So you don’t really replace them.
The acceptance of blocks is entirely up to the method, they can be specified in the method declaration:
which will allow the block to be accessed as a variable from within the method, and be invoked via
block.callfor example.They can also be used implicitely via the use of the
yieldkeyword:So you have to refer to the API documentations to be sure what is accepted or not.