You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/tutorials/basics/70_blocks.md
+70-15Lines changed: 70 additions & 15 deletions
Original file line number
Diff line number
Diff line change
@@ -98,12 +98,7 @@ The abstracted structure declared in the `with_array` method is very common and
98
98
99
99
## Blocks with parameters
100
100
101
-
Like methods, _blocks_ may receive parameters:
102
-
103
-
```crystal
104
-
some_method do |param1, param2, param3|
105
-
end
106
-
```
101
+
Like methods, _blocks_ may receive parameters declared like this: `| param1, param2, ... |`.
107
102
108
103
Let's see an example:
109
104
@@ -112,7 +107,7 @@ def other_method
112
107
yield 42, "Hello", [1, "Crystal", 3]
113
108
end
114
109
115
-
other_method do |n, s, arr|
110
+
other_method do |n, s, arr| # here the block declare 3 parameters
116
111
puts "#{s} #{arr[1]}"
117
112
puts n
118
113
end
@@ -134,7 +129,9 @@ end
134
129
135
130
### Unpacking parameters
136
131
137
-
Let's suppose we have an array of arrays and our _block_ prints each element in each array. One way to implement this would be:
132
+
Now let's suppose we have an array of arrays. And we want to print each array in the following way: _the first element followed by a hyphen, followed by the second element_.
133
+
134
+
One way to implement this would be:
138
135
139
136
```crystal-play
140
137
arr = [["one", 42], ["two", 24]]
@@ -143,7 +140,7 @@ arr.each do |arg|
143
140
end
144
141
```
145
142
146
-
This works, but there is a concise way of writing the same but using parameter unpacking:
143
+
This works, but there is a more readable way of writing the same but using parameter unpacking::
147
144
148
145
```crystal-play
149
146
arr = [["one", 42], ["two", 24]]
@@ -152,13 +149,13 @@ arr.each do |(word, number)|
152
149
end
153
150
```
154
151
155
-
**Note:** we use parentheses to unpack the argument in the different block parameters.
152
+
**Note:** we use parentheses to unpack the argument into the different block parameters.
156
153
157
154
Unpacking arguments into parameters works only if the argument's type responds to `[i]` (with `i` an `integer`). In our example `Array` inherits [Indexable#[]](https://crystal-lang.org/api/latest/Indexable.html#%5B%5D%28index%3AInt%29-instance-method)
158
155
159
156
### Splats
160
157
161
-
When the expected _block_argument is a [Tuple](../syntax_and_semantics/literals/tuple.html) we can use auto-splatting (see [Splats](../syntax_and_semantics/operators.html#splats)) as a way of destructuring the `tuple` in block parameters (and without the need of parentheses).
158
+
When the _block_parameter is a [Tuple](../syntax_and_semantics/literals/tuple.html) we can use auto-splatting (see [Splats](../syntax_and_semantics/operators.html#splats)) as a way of destructuring the `tuple` in block parameters (and without the need of parentheses).
162
159
163
160
164
161
```crystal-play
@@ -168,9 +165,9 @@ arr.each do |word, number|
168
165
end
169
166
```
170
167
171
-
**Note:**`Tuples` also implements [Tuple#[]](https://crystal-lang.org/api/latest/Tuple.html#%5B%5D%28index%3AInt%29-instance-method) meaning that we also can use _unpacking_.
168
+
**Note:**`Tuples` also implements [Tuple#[]](https://crystal-lang.org/api/latest/Tuple.html#%5B%5D%28index%3AInt%29-instance-method) meaning that we can also use _unpacking_.
172
169
173
-
### Block's returned value
170
+
##Blocks' returned value
174
171
175
172
A _block_, by default, returns the value of the last expression (the same as a method).
176
173
@@ -185,7 +182,7 @@ with_number(41) do |number|
185
182
end
186
183
```
187
184
188
-
####Returning keywords
185
+
### Returning keywords
189
186
190
187
We can use the `return` keyword ... but, let's see the following example:
191
188
@@ -285,11 +282,69 @@ end
285
282
test_number(-1)
286
283
```
287
284
288
-
The ouput is
285
+
The output is
289
286
290
287
```console
291
288
292
289
Inside `#test_number` method after `#with_number`
293
290
```
294
291
295
292
As we can see the behaviour is something between using `return` and `next`. With `break` we return from the _block_ and from the method yielding the _block_ (`#with_number` in this example) but not from the method where the `block` is defined.
293
+
294
+
## Type restrictions
295
+
296
+
Until now we have been using _blocks_ without any kind of type restrictions, moreover, we did not declare the block as a method parameter (it was implied by the use of `yield`).
297
+
298
+
So first, we will declare a _block_ as a method parameter: it should be placed last and the parameter's name should be prefixed by `&`. Then we can use `yield` as before.
299
+
300
+
```crystal-play
301
+
def transform_string(word, &block)
302
+
block_result = yield word
303
+
puts block_result
304
+
end
305
+
306
+
transform_string "crystal" do |word|
307
+
word.capitalize
308
+
end
309
+
```
310
+
311
+
Now, we can add type restrictions to our method's parameters:
0 commit comments