When working with method
in ruby
, you may encounter cases where the parameters defined in the method
will be of the form: *args
, **kwargs
, &block
, … So what are they, today we will find Understand this issue via the ruby method parameters
Default parameters
- When defining a
method
, we can specify adefault
value for them. When amethod
is called, if thearguments
values are less than the previously declaredparameters
values then the default parameters will use those default assigned values.123456789<span class="token keyword">def</span> <span class="token method-definition"><span class="token function">info</span></span> <span class="token punctuation">(</span> name <span class="token punctuation">,</span> sex <span class="token operator">=</span> <span class="token string">"male"</span> <span class="token punctuation">)</span>puts <span class="token string">"Name: <span class="token interpolation"><span class="token delimiter tag">#{</span> name <span class="token delimiter tag">}</span></span> , with sex: <span class="token interpolation"><span class="token delimiter tag">#{</span> sex <span class="token delimiter tag">}</span></span> "</span><span class="token keyword">end</span>info <span class="token punctuation">(</span> <span class="token string">"huy"</span> <span class="token punctuation">,</span> <span class="token string">"female"</span> <span class="token punctuation">)</span><span class="token comment"># => Name: huy, with sex: female</span>info <span class="token punctuation">(</span> <span class="token string">"huy"</span> <span class="token punctuation">)</span><span class="token comment"># => Name: huy, with sex: male</span> - If there is more than one
default parameter
in themethod
definition, theseparameters
must be contiguous. For example, it is not possible to put anotherparameter
between the twodefault parameter
. method
has more than onedefault parameter
when executed with a list ofarguments
passed in, thesearguments
will be valued for thedefault parameters
from left to right:1234567891011<span class="token keyword">def</span> <span class="token method-definition"><span class="token function">f</span></span> <span class="token punctuation">(</span> a <span class="token punctuation">,</span> b <span class="token operator">=</span> <span class="token number">1</span> <span class="token punctuation">,</span> c <span class="token operator">=</span> <span class="token number">2</span> <span class="token punctuation">)</span>puts a <span class="token punctuation">,</span> b <span class="token punctuation">,</span> c<span class="token keyword">end</span>f <span class="token punctuation">(</span> <span class="token number">10</span> <span class="token punctuation">)</span><span class="token comment"># => 10, 1, 2</span>f <span class="token punctuation">(</span> <span class="token number">10</span> <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">)</span><span class="token comment"># => 10, 100, 2</span>f <span class="token punctuation">(</span> <span class="token number">10</span> <span class="token punctuation">,</span> <span class="token number">100</span> <span class="token punctuation">,</span> <span class="token number">200</span> <span class="token punctuation">)</span><span class="token comment"># => 10, 100, 200</span>
Parameter with splat operator (*)
- The array type parameter marked with the
*
in front is used when passing an array of any arguments:1234567<span class="token keyword">def</span> <span class="token method-definition"><span class="token function">f</span></span> <span class="token punctuation">(</span> first <span class="token punctuation">,</span> <span class="token operator">*</span> rest <span class="token punctuation">)</span>puts rest <span class="token punctuation">,</span> rest <span class="token punctuation">.</span> <span class="token keyword">class</span><span class="token class-name">end</span>f <span class="token punctuation">(</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token number">2</span> <span class="token punctuation">,</span> <span class="token number">3</span> <span class="token punctuation">,</span> <span class="token number">4</span> <span class="token punctuation">)</span><span class="token comment"># => [2, 3, 4], Array</span> - A
method
has no more than one parameter of this type, an array type parameter must be adjacent to the default parameters, and may precede other normal parameters:1234567<span class="token keyword">def</span> <span class="token method-definition"><span class="token function">f</span></span> <span class="token punctuation">(</span> a <span class="token operator">=</span> <span class="token number">1</span> <span class="token punctuation">,</span> <span class="token operator">*</span> args <span class="token punctuation">,</span> b <span class="token punctuation">)</span>puts <span class="token string">"a: <span class="token interpolation"><span class="token delimiter tag">#{</span> a <span class="token delimiter tag">}</span></span> , args: <span class="token interpolation"><span class="token delimiter tag">#{</span> args <span class="token delimiter tag">}</span></span> , b: <span class="token interpolation"><span class="token delimiter tag">#{</span> b <span class="token delimiter tag">}</span></span> "</span><span class="token keyword">end</span>f <span class="token punctuation">(</span> <span class="token number">10</span> <span class="token punctuation">,</span> <span class="token number">20</span> <span class="token punctuation">,</span> <span class="token number">30</span> <span class="token punctuation">,</span> <span class="token number">40</span> <span class="token punctuation">)</span><span class="token comment"># => a: 10, args: [20, 30], b: 40</span> - Additionally,
*
also used when we want to pass an array of arguments when we call themethod
:
1 2 3 4 5 6 7 8 | <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">f</span></span> <span class="token punctuation">(</span> name <span class="token punctuation">,</span> age <span class="token punctuation">,</span> sex <span class="token punctuation">)</span> puts name <span class="token punctuation">,</span> age <span class="token punctuation">,</span> sex <span class="token keyword">end</span> user <span class="token operator">=</span> <span class="token punctuation">[</span> <span class="token string">"sherlock"</span> <span class="token punctuation">,</span> <span class="token number">20</span> <span class="token punctuation">,</span> <span class="token string">"male"</span> <span class="token punctuation">]</span> f <span class="token punctuation">(</span> <span class="token operator">*</span> user <span class="token punctuation">)</span> <span class="token comment"># => sherlock, 20, male</span> |
Mapping arguments to parameters
We will learn how ruby
assigns arguments passed to the parameters defined in the method
.
Suppose a method
has o
original
parameters (normal parameters), d
parameters are assigned default values, and 1 parameters are array type. method
is called with a
argument, then:
- If
a < o
: anArgumentError
occurs - If
o <= a <= o+d
:ao
default parameter will be assigned value, the rest,o+da
default parameter will use the original default value. - If
a > o+d
:aod
theaod
argument will be assigned to the last array parameter
Using hash for named arguments
When a method
requires more than 2 or 3 parameters, it is very difficult to execute this method
, we need to remember the order of all these parameters when passing the arguments. To solve this problem, in ruby
we can use the hash argument
:
1 2 3 4 5 6 7 | <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">f</span></span> <span class="token punctuation">(</span> opts <span class="token punctuation">)</span> puts opts <span class="token keyword">end</span> f <span class="token punctuation">(</span> <span class="token punctuation">{</span> name <span class="token punctuation">:</span> <span class="token string">"huy"</span> <span class="token punctuation">,</span> age <span class="token punctuation">:</span> <span class="token number">11</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token comment"># => {:name=>"huy", :age=>11}</span> |
- If in the
method
the hash is at the end (or is followed by ablock
), we can omit the{}
sign when calling themethod
:123f <span class="token punctuation">(</span> name <span class="token punctuation">:</span> <span class="token string">"huy"</span> <span class="token punctuation">,</span> age <span class="token punctuation">:</span> <span class="token number">11</span> <span class="token punctuation">)</span><span class="token comment"># => {:name=>"huy", :age=>11}</span>
Parameter with double splat (**) operator
One more way to declare a parameter of type hash: use **
:
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">f</span></span> <span class="token punctuation">(</span> <span class="token operator">*</span> <span class="token operator">*</span> hash <span class="token punctuation">)</span> puts hash <span class="token keyword">end</span> f <span class="token punctuation">(</span> a <span class="token punctuation">:</span> <span class="token number">1</span> <span class="token punctuation">,</span> b <span class="token punctuation">:</span> <span class="token number">2</span> <span class="token punctuation">)</span> <span class="token comment"># => {:a=>1, :b=>2}</span> f <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token comment"># Nếu không truyền đối số nào, mặc định cho `hash` sẽ là `{}`</span> <span class="token comment"># => {}</span> |
Block arguments with (&)
- A
block
may be passed when calling themethod
:1234567<span class="token keyword">def</span> <span class="token method-definition"><span class="token function">f</span></span> <span class="token punctuation">(</span> name <span class="token punctuation">,</span> <span class="token operator">&</span> block <span class="token punctuation">)</span><span class="token keyword">yield</span> name<span class="token keyword">end</span>f <span class="token punctuation">(</span> <span class="token string">"sherlock"</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token operator">|</span> name <span class="token operator">|</span> puts name <span class="token punctuation">}</span><span class="token comment"># => sherlock</span>
If in the parameter list there is no&
, theblock
can still be passed via{}
ordo; ;end
- Note that the parameter with
&
is defined only once, and it must be placed at the bottom of the list:
1 2 3 4 5 6 7 8 9 10 11 | <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">f</span></span> <span class="token punctuation">(</span> <span class="token operator">&</span> block <span class="token punctuation">,</span> <span class="token operator">&</span> other_block <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token keyword">end</span> <span class="token comment"># => syntax error, unexpected ',', expecting ')'</span> <span class="token keyword">def</span> <span class="token method-definition"><span class="token function">f</span></span> <span class="token punctuation">(</span> <span class="token operator">&</span> block <span class="token punctuation">,</span> name <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token punctuation">.</span> <span class="token keyword">end</span> <span class="token comment"># => syntax error, unexpected ',', expecting ')'</span> |