From: matthew@... Date: 2014-01-20T00:23:38+00:00 Subject: [ruby-core:59879] [ruby-trunk - Feature #9428] Inline argument expressions and re-assignment Issue #9428 has been updated by Matthew Kerwin. I'm -1 for this. 1. aesthetically: it puts some of the function's code outside the function's body, which makes it harder to follow a function's execution when reading code, and it makes the signature unnecessarily messy. 2. syntactically: none of the proposals you've given make enough sense, at least for me personally to understand what they mean: def foo( arg.to_i ) def foo( arg.to_i as arg ) Is the left-most 'arg' a local variable, or referring to self#arg, or something else..? > Ruby could auto-assign the passed argument to the first variable encountered in the expression. According to my understanding of the parser, any heretofore unseen "bareword" tokens are interpreted as function calls, so there is no "first variable encountered." It works for optional positional parameters because they have an equals sign in (and 'bareword = expression' is universally lvar creation/assignment, in Ruby). 3. debugability: the 'def' line is a single line, however there's no real limit to the number of parameters you can include in that line. If each of those parameters can include arbitrary expressions, well, I'd hate to have to debug a "NoMethodError: undefined method ... for nil:NilClass" on that line. And if the answer to that is to split the 'def' line over multiple lines, then why not just put the expressions on those multiple lines anyway? 4. orthogonality: what about non-optional keyword arguments? For what it's worth, I'm not entirely *for* allowing arbitrary expressions in optional parameters either, but in that case I can't think of a better representation. But if I ever seen anything more than a #[] call in a default value I consider it Bad Form���. -- Matthew Kerwin http://matthew.kerwin.net.au/ ---------------------------------------- Feature #9428: Inline argument expressions and re-assignment https://bugs.ruby-lang.org/issues/9428#change-44435 * Author: Tom Wardrop * Status: Open * Priority: Normal * Assignee: * Category: core * Target version: ---------------------------------------- Just a random idea. Currently, Ruby allows you to use any arbitrary expression for setting default values for arguments, which can be really convenient and makes for clear code, especially handy for documentation, etc. For example: def fetch(id, cache = config[:cache]) # bleh end In the same vein, as well as setting a default value using an arbitrary expression, it's not uncommon to *post-process* an argument, some common examples include: arg = arg.upcase arg = arg.to_sym arg = arg.dup It would be rather nice in my opinion to be able to do this inline when defining the argument: def fetch(id.to_i, cache = config[:cache]) # bleh end This works well where the argument is the receiver of the method call, but what if you wanted to do `Integer(id)` in the above example instead of using String#to_i? There are two options. One could either fallback to processing the argument within the method/block body, or, you could make the implementation a little bit clever by using inferencing. Ruby could auto-assign the passed argument to the first variable encountered in the expression. So in the following example, as soon as the virtual machine encounters `id`, it recognises it as a variable and assigns the argument value before continuing. When encountering subsequent variables, Ruby would take the usual action and look for a corresponding method in `self` before throwing an error. You can always disambiguate by qualifying the receiver, e.g. `self.id` def fetch(Integer(id), cache = config[:cache]) # bleh end Whatever the result of the expression, it's assigned as the final argument value. So in the case of `id.to_i`, the argument name of `id` is inferred. `id` is set to the supplied argument for the duration of the expression. The result of the expression is then re-assigned as the value of `id`. This technically allows expressions of arbitrary complexity, but like all things in Ruby, with great power comes great responsibility. One must use common sense when deciding whether to manipulate the argument inline, or within the method body. As long as the expression is of reasonable length and complexity, readability remains perfectly reasonable. Interested to get some thoughts and opinions on this one. I sense the potential for controversy :) -- http://bugs.ruby-lang.org/