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> |