Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions docs/syntax_and_semantics/block_forwarding.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def capture(&block)
block
end

def twice
def twice(&)
yield
yield
end
Expand Down Expand Up @@ -67,11 +67,11 @@ twice &->say_hello
To forward non-captured blocks, you must use `yield`:

```crystal
def foo
def foo(&)
yield 1
end

def wrap_foo
def wrap_foo(&)
puts "Before foo"
foo do |x|
yield x
Expand All @@ -92,7 +92,7 @@ end
You can also use the `&block` syntax to forward blocks, but then you have to at least specify the input types, and the generated code will involve closures and will be slower:

```crystal
def foo
def foo(&)
yield 1
end

Expand Down
38 changes: 20 additions & 18 deletions docs/syntax_and_semantics/blocks_and_procs.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Methods can accept a block of code that is executed
with the `yield` keyword. For example:

```crystal
def twice
def twice(&)
yield
yield
end
Expand All @@ -16,7 +16,7 @@ end

The above program prints "Hello!" twice, once for each `yield`.

To define a method that receives a block, simply use `yield` inside it and the compiler will know. You can make this more evident by declaring a dummy block parameter, indicated as a last parameter prefixed with ampersand (`&`):
To define a method that receives a block, simply use `yield` inside it and the compiler will know. You can make this more evident by declaring a dummy block parameter, indicated as a last parameter prefixed with ampersand (`&`). In the example above we did this, making the argument anonymous (writing just the `&`). But it can be given a name:

```crystal
def twice(&block)
Expand All @@ -25,6 +25,8 @@ def twice(&block)
end
```

The block parameter name is irrelevant in this example, but will be relevant in more advanced uses.

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

```crystal
Expand Down Expand Up @@ -88,7 +90,7 @@ Two methods, one that yields and another that doesn't, are considered different
The `yield` expression is similar to a call and can receive arguments. For example:

```crystal
def twice
def twice(&)
yield 1
yield 2
end
Expand All @@ -109,7 +111,7 @@ twice { |i| puts "Got #{i}" }
You can `yield` many values:

```crystal
def many
def many(&)
yield 1, 2, 3
end

Expand All @@ -123,7 +125,7 @@ end
A block can specify fewer parameters than the arguments yielded:

```crystal
def many
def many(&)
yield 1, 2, 3
end

Expand All @@ -137,7 +139,7 @@ end
It's an error specifying more block parameters than the arguments yielded:

```crystal
def twice
def twice(&)
yield
yield
end
Expand All @@ -149,7 +151,7 @@ end
Each block parameter has the type of every yield expression in that position. For example:

```crystal
def some
def some(&)
yield 1, 'a'
yield true, "hello"
yield 2, nil
Expand All @@ -164,7 +166,7 @@ end
The [underscore](assignment.md#underscore) is also allowed as a block parameter:

```crystal
def pairs
def pairs(&)
yield 1, 2
yield 2, 4
yield 3, 6
Expand Down Expand Up @@ -239,7 +241,7 @@ method(&.[index])
The `yield` expression itself has a value: the last expression of the block. For example:

```crystal
def twice
def twice(&)
v1 = yield 1
puts v1

Expand All @@ -265,7 +267,7 @@ ary.select { |x| x % 2 == 1 } # => [1, 3]
A dummy transformation method:

```crystal
def transform(value)
def transform(value, &)
yield value
end

Expand Down Expand Up @@ -293,7 +295,7 @@ transform_int(3) { |x| "foo" } # Error: expected block to return Int32, not Stri
A `break` expression inside a block exits early from the method:

```crystal
def thrice
def thrice(&)
puts "Before 1"
yield 1
puts "Before 2"
Expand All @@ -315,7 +317,7 @@ The above prints "Before 1" and "Before 2". The `thrice` method didn't execute t
`break` can also accept arguments: these become the method's return value. For example:

```crystal
def twice
def twice(&)
yield 1
yield 2
end
Expand Down Expand Up @@ -357,7 +359,7 @@ value # => nil
The `next` expression inside a block exits early from the block (not the method). For example:

```crystal
def twice
def twice(&)
yield 1
yield 2
end
Expand All @@ -379,7 +381,7 @@ end
The `next` expression accepts arguments, and these give the value of the `yield` expression that invoked the block:

```crystal
def twice
def twice(&)
v1 = yield 1
puts v1

Expand Down Expand Up @@ -412,11 +414,11 @@ class Foo
1
end

def yield_with_self
def yield_with_self(&)
with self yield
end

def yield_normally
def yield_normally(&)
yield
end
end
Expand Down Expand Up @@ -477,7 +479,7 @@ end
When using blocks with `yield`, the blocks are **always** inlined: no closures, calls or function pointers are involved. This means that this:

```crystal
def twice
def twice(&)
yield 1
yield 2
end
Expand Down Expand Up @@ -510,7 +512,7 @@ This is `Int#times` definition:

```crystal
struct Int
def times
def times(&)
i = 0
while i < self
yield i
Expand Down
2 changes: 1 addition & 1 deletion docs/syntax_and_semantics/closures.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ In the above example, even though `x` is a local variable, it was captured by th
The compiler is usually moderately smart about the type of local variables. For example:

```crystal
def foo
def foo(&)
yield
end

Expand Down
2 changes: 1 addition & 1 deletion docs/syntax_and_semantics/macros/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Foo
"***#{ {{value}} }***"
end

def yield_with_self
def yield_with_self(&)
with self yield
end
end
Expand Down
4 changes: 2 additions & 2 deletions docs/syntax_and_semantics/next.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ end
`next` can also be used to exit from a block, for example:

```crystal
def block
def block(&)
yield
end

Expand All @@ -34,7 +34,7 @@ end
Similar to [`break`](break.md), `next` can also take an argument which will then be returned by `yield`.

```crystal
def block
def block(&)
puts yield
end

Expand Down
2 changes: 1 addition & 1 deletion docs/syntax_and_semantics/overloading.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class Person

# Yields the current age of this person and increases
# its age by the value returned by the block
def become_older
def become_older(&)
@age += yield @age
end
end
Expand Down