Submitted by: Ron Hopper
This revision by: Ron Hopper
Date: Mon Mar 19 16:55:49 -0500 2007
There are assignment shortcuts for most binary operators, however, the ternary if-then-else operator does not have a shortcut for assignment. In some situations this shortcut makes a lot of sense and its lack is noticeable.
There are frequently scenarios when a variable needs to be replaced by a modified version of itself or a default value if it is nil. Assignment in these scenarios is achieved using the ternary if-then-else operator to check for a nil value and supply a default. There is unnecessary duplication, however, in the common case that the variable being assigned to is the same one being checked, as in these examples:
page_title = page_title ? "Title: #{page_title}" : "Untitled"
tree_node = tree_node ? tree_node.next : root_node
Allow the assigment shortcut syntax for the ternary if-then-else operator, so that code previously written as:
page_title = page_title ? "Title: #{page_title}" : "Untitled"
tree_node = tree_node ? tree_node.next : root_node
can instead be written more meaningfully and succinctly as:
page_title ?= "Title: #{page_title}" : "Untitled"
tree_node ?= tree_node.next : root_node
The change is trivial, does not create any language conflicts that I am aware of, and makes the code more concise while improving readability.
The syntax:
x ?= y : z
should be expanded to
x = x ? y : z
On 3/19/07, matz@ruby-lang.org <matz@ruby-lang.org> wrote: > A comment about: RCR 7: If-then-else Assignment Shortcut > was sent by Yukihiro Matsumoto. > > To send a comment, reply to this mail. Please trim all unnecessary > lines. > > You can view RCR 7 at: > https://rcrchive.net/rcrs/9 > > Hi, > > I have never met a situation of needing it. Do you? > Maybe it's upto programming style. Whereas I find "||=" useful. > > a ||= b > > is roughly equivalent to > > a = a ? a : b Yep ||= does the trick. Tough I thought it was odd to hear that a = b unless a executed faster. Is that true? A little OT, but I sometimes run into return a if a would be nice if one could do return_on a or something like that (especially useful when "a" is complex). T.
Hi, I have never benchmarked between a ||= b and a = b unless a but I'm sure the difference would be trivial, and situation will change after YARV. For return_on statement you have proposed, I am negative for it, since we should be conservative for adding new reserved words, especially one that change control flow. I feel return_on complex_expression is no better than x = complex_expression return x if x It's explicit and more understandable at the cost of little verbosity (only 7 bytes longer), besides that I have never met the situation for code like that. matz.
On 3/19/07, matz@ruby-lang.org <matz@ruby-lang.org> wrote: > A comment about: RCR 7: If-then-else Assignment Shortcut > was sent by Yukihiro Matsumoto. > > To send a comment, reply to this mail. Please trim all unnecessary > lines. > > You can view RCR 7 at: > https://rcrchive.net/rcrs/9 > > Hi, > > I have never benchmarked between > > a ||= b > > and > > a = b unless a > > but I'm sure the difference would be trivial, and situation will > change after YARV. > > For return_on statement you have proposed, I am negative for it, since > we should be conservative for adding new reserved words, especially > one that change control flow. I feel > > return_on complex_expression > > is no better than > > x = complex_expression > return x if x Well you'd usually write it like if x = complex_expression return x end I would write it one line return x if x = complex_expression but that fails to assign the x before the return, maybe that will be fixed in YARV? > It's explicit and more understandable at the cost of little verbosity > (only 7 bytes longer), besides that I have never met the situation for > code like that. I've used it more than a few times. I'd have to look for one though, I'm not very good at thinking up good examples off the top of my head. When I run across it again I'll let you know. In any case I understand about the additional keyword. Just wish there were a more elegant way to write it. T.
Hi, In message "Re: [RCR] If-then-else Assignment Shortcut" on Mon, 19 Mar 2007 19:46:59 -0500, transfire@gmail.com writes: |I would write it one line | | return x if x = complex_expression | |but that fails to assign the x before the return, maybe that will be |fixed in YARV? Not for 1.9, it will be in 2.0. matz.
On 3/19/07, matz@ruby-lang.org < matz@ruby-lang.org> wrote: > > I have never met a situation of needing it. Do you? > Maybe it's upto programming style. Whereas I find "||=" useful. > > a ||= b > > is roughly equivalent to > > a = a ? a : b > > matz. While ||= is very useful for assigning a default value, it does not apply to the case when a calculation must be performed on a non-nil value. There are two scenarios where I typically run into this. 1) When using potentially nil-valued string variables that require some processing, such as appending a suffix or modifying case. For example, I recently wrote a script to define wizard-related methods in a Rails controller. def wizard_actions define_method "edit" do #... end define_method "save_as_draft" do #... end # etc. end I was later able to use this code in a case that required more explicit method names, such as "edit_profile". I would like to have modified the code as below: def wizard_actions(suffix = nil) suffix ?= "_#{suffix}" : "" define_method "edit#{suffix}" do #... end define_method "save#{suffix}" do #... end # etc. end Instead, I used: def wizard_actions(suffix = "") suffix = "_#{suffix}" unless suffix.blank? I believe that the ternary shortcut would be more appropriate, however, and can't see why it's excluded from the assignment shortcuts. 2) When managing data-structures, it is a useful way to avoid calling methods on nil pointers. As a simplified example, consider a singly linked list with a method to remove the next node in the list. class SinglyLinkedList #... class Node attr_accessor :next, :value def initialize(value) @next = nil @value = value end def remove_next @next ?= @next.next : nil end #...etc. end end Although, these examples are not encountered frequently compared to uses of the other assignment shortcuts, it seems to me that there is little reason not to allow this shortcut which is occasionally useful and fits well with the other operator conventions. On 3/19/07, <b class="gmail_sendername"><a href="mailto:matz@ruby-lang.org" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">matz@ruby-lang.org</a></b> <<a href="mailto:matz@ruby-lang.org" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)"> matz@ruby-lang.org</a>> wrote:<div><span class="gmail_quote"></span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"> I have never met a situation of needing it. Do you?<br>Maybe it's upto programming style. Whereas I find "||=" useful.<br><br> a ||= b<br><br>is roughly equivalent to<br><br> a = a ? a : b<br><br> matz. </blockquote><div><br><br>While ||= is very useful for assigning a default value, it does not apply to the case when a calculation must be performed on a non-nil value. There are two scenarios where I typically run into this. <br><br>1) When using potentially nil-valued string variables that require some processing, such as appending a suffix or modifying case. For example, I recently wrote a script to define wizard-related methods in a Rails controller. <br><br> def wizard_actions<br> define_method "edit" do<br> #...<br> end<br> <br> define_method "save_as_draft" do<br> #...<br> end<br> <br> # etc.<br> end<br><br>I was later able to use this code in a case that required more explicit method names, such as "edit_profile". I would like to have modified the code as below: <br><br> def wizard_actions(suffix = nil)<br> suffix ?= "_#{suffix}" : ""<br> <br> define_method "edit#{suffix}" do<br> #...<br> end<br> <br> define_method "save#{suffix}" do <br> #...<br> end<br> <br> # etc.<br> end<br><br>Instead, I used:<br><br> def wizard_actions(suffix = "")<br> suffix = "_#{suffix}" unless suffix.blank?<br> <br>I believe that the ternary shortcut would be more appropriate, however, and can't see why it's excluded from the assignment shortcuts.<br><br>2) When managing data-structures, it is a useful way to avoid calling methods on nil pointers. As a simplified example, consider a singly linked list with a method to remove the next node in the list. <br><br>class SinglyLinkedList<br><br> #...<br><br> class Node<br> attr_accessor :next, :value<br> <br> def initialize(value)<br> @next = nil<br> @value = value<br> end<br><br> def remove_next<br> @next ?= @next.next : nil<br> end<br><br> #...etc.<br> end<br>end<br><br>Although, these examples are not encountered frequently compared to uses of the other assignment shortcuts, it seems to me that there is little reason not to allow this shortcut which is occasionally useful and fits well with the other operator conventions. <br></div></div>
Copyright © 2006, Ruby Power and Light, LLC
Comments
from Yukihiro Matsumoto, Mon Mar 19 18:50:38 -0500 2007