From: Matthew Kerwin Date: 2014-01-20T12:33:23+10:00 Subject: [ruby-core:59883] Re: [ruby-trunk - Feature #9428] Inline argument expressions and re-assignment --047d7b3435b63bcd9104f05db715 Content-Type: text/plain; charset=ISO-8859-1 On 20 January 2014 10:41, wrote: > Issue #9428 has been updated by Tom Wardrop. > > > 1. I know you said you're not a fan of allowing expression when assigning > default values to optional parameters, but the point about aesthetics > applies equally to them also. > That's partly why I'm not a fan. If I could think of a valid, useful alternative I would strongly suggest it. I know it wouldn't be adopted (backwards compatibility, if nothing else) but I'd propose it anyway. The best I can come up with is another special method, along the lines of method_given?, perhaps: def foo bar, baz=? # no idea what syntax to propose here baz = 42 unless argument_given? :baz end It's not great, obviously, but it removes arbitrary code from the 'def' line. > 1. The rule is relatively simple. The first identifier (lvar/method) > encountered is automatically assigned the value of the argument passed to > the method or proc. That's the rule, the first identifier (valid variable > name) is assigned the argument value. If you want to refer to `self.id`, > you must use `self.id` to disambiguate as you would have to in many other > scenario's in Ruby. In the example you highlighted `def foo( arg.to_i )`, > the identifier `arg` is encountered and automatically assigned the argument > value before the expression continues execution. > "First encountered" in regular left-to-right parsing order? def foo( a[b] ) #=> def foo a a = a[b] end ? > 1. The same problem exists for expressions used as default values for > optional arguments. Debugging is the same for each. If it's not clear > where the error occurred, one could always temporarily break the argument > definitions over multiple lines while debugging. I don't think debugging > would be any worse than debugging a long method chain like `Hash[var.select > { |v| #bleh }.map { |v| # blah }]`. I therefore don't think debugability > can be used against this proposal. > I agree that existing long/complex lines are hard to debug. But why add the opportunity for more such lines? Especially in a place that is traditionally free from such concerns? With my background as a C programmer I instinctively see the 'def' line as free from execution; it's a definition, something that informs the interpreter and the human reader about the nature of the program/data/etc. I would be surprised if I started seeing runtime exceptions raised from these traditionally compile-time-only lines. Again, I know it's already possible to achieve these errors using optional args, but I concede that as a necessary evil in the absence of an alternative. And, since we're stuck with them, I prefer a culture of promoting the least amount of executable code possible in that line; thus some of my opposition to this proposal. > 1. Technically, for optional arguments, you can have an expression for > when an argument is given, and an expression for when an argument is > optional. It remains consistent in this respect. > > `def foo(id.to_i = config[:default_id])` This introduces some amount of confusion. Which of the following is equivalent? id = id.to_i // id = config[:default_id] or: id = id.to_i // id = config[:default_id].to_i Either way, this is very confusing when, anywhere else in a Ruby script, it would mean: id.to_i=( config[:default_id] ) -- Matthew Kerwin http://matthew.kerwin.net.au/ --047d7b3435b63bcd9104f05db715 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable
= On 20 January 2014 10:41, <tom@tomwardrop.com> wrote:
Issue #9428 has been updated by Tom Wardrop.


1. I know you said you're not a fan of allowing expression when assigni= ng default values to optional parameters, but the point about aesthetics ap= plies equally to them also.

That's partly why I'm not a fan. =A0If I could think of a valid, us= eful alternative I would strongly suggest it. =A0I know it wouldn't be = adopted (backwards compatibility, if nothing else) but I'd propose it a= nyway. =A0The best I can come up with is another special method, along the = lines of method_given?, perhaps:

=A0 def foo bar, baz=3D? =A0# no idea what synt= ax to propose here
=A0 =A0 baz =3D 42 unless argument_given? :baz
=A0 e= nd

It's not great, obviously, but it removes arbitrary= code from the 'def' line.

=A0
1. The rule is relatively simple. The first identifier (lvar/method) encoun= tered is automatically assigned the value of the argument passed to the met= hod or proc. That's the rule, the first identifier (valid variable name= ) is assigned the argument value. If you want to refer to `self.id`, you must use `self.id` to disambiguate as you would have t= o in many other scenario's in Ruby. In the example you highlighted `def= foo( arg.to_i )`, the identifier `arg` is encountered and automatically as= signed the argument value before the expression continues execution.

"First encountered" in = regular left-to-right parsing order?

=A0 def foo( a[b] )
#=3D>
=A0 def foo a<= br>
=A0 =A0 a =3D a[b]
=A0 end

?

=A0
1. The same problem exists for expressions used as default values for optio= nal arguments. =A0Debugging is the same for each. If it's not clear whe= re the error occurred, one could always temporarily break the argument defi= nitions over multiple lines while debugging. I don't think debugging wo= uld be any worse than debugging a long method chain like `Hash[var.select {= |v| #bleh }.map { |v| # blah }]`. I therefore don't think debugability= can be used against this proposal.

I agree that existing long/comple= x lines are hard to debug. =A0But why add the opportunity for more such lin= es? =A0Especially in a place that is traditionally free from such concerns?= =A0With my background as a C programmer I instinctively see the 'def&#= 39; line as free from execution; it's a definition, something that info= rms the interpreter and the human reader about the nature of the program/da= ta/etc. =A0I would be surprised if I started seeing runtime exceptions rais= ed from these traditionally compile-time-only lines.

Again, I know it's already possible to achi= eve these errors using optional args, but I concede that as a necessary evi= l in the absence of an alternative. =A0And, since we're stuck with them= , I prefer a culture of promoting the least amount of executable code possi= ble in that line; thus some of my opposition to this proposal.

=A0
1. Technically, for optional arguments, you can have an expression for when= an argument is given, and an expression for when an argument is optional. = It remains consistent in this respect.

=A0 =A0 `def foo(id.to_i =3D config[:default_id])`

This introduces some amount of confusion. Which of the followin= g is equivalent?

=A0 id =3D id.to_i // id =3D config[:default_id= ]

or:

=A0 id =3D id.to_i // id =3D config[:default_id].to_i

Either way, this is very confusing when, anywhere else in a Ruby script, it= would mean:

=A0 id.to_i=3D( config[:default_id] )


--
=A0 Matthew Kerwin
=A0 http://matthew.kerwin.net.au/
--047d7b3435b63bcd9104f05db715--