Variable Arguments
-
Rails uses quite a few techniques to make the end-user API a little nicer when you’re creating your applications. One of these techniques is having a method accept variable arguments with a hash of options. We see this pattern appear in quite a few different areas of the Rails API, particularly in ActiveRecord and ActionView.
An an example, we can specify a variable number of attributes when we perform model validation. Take a look at how we validate the presence of both the
nameandageattributes for a model along with a custom error message as the final argument.Ruby
class User < ActiveRecord::Base validates_presence_of :name, :age, :message => "Can't be empty!" end
We also see this pattern used in various built-in view helper methods. When we want to include multiple stylesheets in our application, we can specify multiple sources using
stylesheet_link_tag.Ruby
<head> <%= stylesheet_link_tag :layout, :colors, :media => "screen" %> </head>
Using variable arguments is often more convenient than calling a function multiple times, and it is a little nicer than passing an array. This trick can be adapted to PHP development pretty easily. The above example looks quite different from PHP when using the common Ruby style.
However, it does map faithfully to PHP if we add back the syntactic noise that we purposely left out. We also talk about this transliteration in the Beginning Ruby Code chapter of the book.
Ruby
<%= stylesheet_link_tag(:layout, :color, {:media => "screen"}) %>
PHP
<?= stylesheetLinkTag('layout', 'color', array('media' => 'screen')) ?>
In PHP we implement variable arguments using using the
func_get_args()function:PHP
function stylesheetLinkTag($sources) { $sources = func_get_args(); foreach ($sources as $source) { // ... } }
Since the
$sourcescome fromfunc_get_args(), no arguments in the function definition are necessary. However, if the function definition has no arguments, PHP will not raise a notice if the function is called with no arguments. Since our function requires at least one argument, it’s useful to have it in the function definition for that reason. It will also get picked up by code documentation tools.Let’s not forget about the optional list of options that we pass in as the final argument. We can extract this data in our PHP function implementation by simply checking if the last value of the variable arguments is an array.
PHP
function stylesheetLinkTag($sources) { $sources = func_get_args(); $last = end($sources); $options = is_array($last) ? array_pop($sources) : array(); // find the stylesheet media attribute $media = isset($options['media']) ? $options['media'] : ''; foreach ($sources as $source) { // ... } }


Post a comment