The Crystal Programming Language Forum

Code blocks do end vs brackets

Hi,
I do not understand the binding difference between the two.
Are the following the same or not ?
function parameter1 parameter2 { dosomething}
function parameter1 parameter2 do dosomething end.
And when does a difference occure.
Thanks,

Checkout this section in the language reference:

https://crystal-lang.org/reference/syntax_and_semantics/blocks_and_procs.html

tl;dr

To invoke a method and pass a block, you use do ... end or { ... }. All of these are equivalent:

twice() do
  puts "Hello!"
end

twice do
  puts "Hello!"
end

twice { puts "Hello!" }

By convention I find it better to use do ... end when the block’s content is longer, while using { ... } for short one line stuff.

I rephrase my question different.
If on any existing program you replace every “do” with “{” and every “end” with “}” , or the inverse.
Will the program compile and behave the same.

The docs say this:

The difference between using do ... end and { ... } is that do ... end binds to the left-most call, while { ... } binds to the right-most call:

And they provide an example too.

The answer is there.

Cheers!

No, it might stop compiling.

This:

foo bar do
end

Is the same as:

foo(bar) do
end

But this:

foo bar {
}

is the same as this:

foo(bar {
})
2 Likes

The following works correctly :
print “hello”
{
print “hello”
}
The following produces an error:
print “hello”
do
print "hello
end

Error : ```
syntax error in eval:2
Error: expecting token ‘EOF’, not ‘do’

Not obvious at first.

Just note that the first snippet:

print “hello”
{
print “hello”
}

it equivalent to:

print “hello” # prints hello
{ print “hello” } # a tuple with one element, that contains the result of printing "hello": nil

You can’t put braces on separate lines like you do in Java or C#.

You can put a closing brace on a separate line, right? It’s just that you get into trouble if you try to put the opening-brace of a code block on a new line. (For that matter, do won’t work if you try to put that on a new line).

Do you think as rule of the thumb i can use everywhere { }
Except when explicit a code block is expected , as after a “5.times”
And use ( ) to avoid confusion.

I still like Weirich’s rule as a good rule of thumb.

1 Like

Yeah. That’s a good one.

Only with examples in the link I would not use a one line version of do..end and format it to span multiple lines.

Similarly { } blocks that return values can be formatted to span multiple lines.