An idea for new syntactic sugar in Ruby

I was looking at this bit of code within Rails:

File actionpack/lib/action_controller/metal/flash.rb, line 12

def redirect_to(options = {}, response_status_and_flash = {}) #:doc:
if alert = response_status_and_flash.delete(:alert)
flash[:alert] = alert
end

if notice = response_status_and_flash.delete(:notice)
flash[:notice] = notice
end

if other_flashes = response_status_and_flash.delete(:flash)
flash.update(other_flashes)
end

super(options, response_status_and_flash)
end

And I thought: ouch, aren’t those supposed to be double-equals? Well,
no, it’s an assignment within an if statement. It saves a line of
code per usage, thus three lines of code in that method.

But I thought: wow, that sure violates the principle of least
surprise. Perhaps it would be nice if there were a way to reference
the most recent if-expression. I recall how a lone underscore in irb
will contain the value of whatever was last evaluated. So perhaps
something like this would be nice:

if response_status_and_flash.delete(:notice)
flash[:notice] = _
end

instead of what we see above:

if notice = response_status_and_flash.delete(:notice)
flash[:notice] = notice
end

end
code per usage, thus three lines of code in that method.

instead of what we see above:

if notice = response_status_and_flash.delete(:notice)
flash[:notice] = notice
end

Interesting, but I think using _ is even more surprising isn’t it? What
happens when you have this…

if something-that-returns-a-value-and-passes-the-if-test
if something-that-returns-a-value-but-fails-the-if-test
# never happens
else
# what does _ reference? The very top level if? Or the second one?
# Both were evaluated, but one failed so does it count towards _ or
not?
# How do I access the first _ if Ruby decides _ is the second one?
end
end

Ok, I found this feature request:

http://redmine.ruby-lang.org/issues/show/1141

It was rejected. I guess one could do:

notice = response_status_and_flash.delete(:notice)
flash[:notice] if notice

It’s one line shorter, and perhaps less confusing. The only drawback
would be that the notice variable stays in scope, which is not so
nice.

I also found this on stackoverflow:

On 15 February 2011 01:18, Kai M. [email protected]
wrote:

end
code per usage, thus three lines of code in that method.

But I thought: wow, that sure violates the principle of least
surprise.

In that situation I would code it as
if ( other_flashes = response_status_and_flash.delete(:flash) )
which arguably makes the intention clearer with only a few extra
characters an no run time penalty.

Colin

Yeah, great point. How to know how deep to go. I was looking at some
of the Ruby global vars:

http://www.rubyist.net/~slagell/ruby/globalvars.html

This one is similar:
$n the nth subexpression in the last match (same as $~[n])

But it seems somehow not so clean.

We have this nifty idiom:

x ||= “hello”

But I can’t think of a neat syntax for what I’m wanting.

On May 20, 2011, at 5:05 PM, Curtis j Schofield wrote:

:smiley:

make haste slowly
festina lente \

mobile +1_415_632_6001
[email protected]
http://robotarmyma.de

assuming that the intent is to call
response_status_and_flash.delete(:notice) just once, test the result,
and then use a truthy result in the flash[:notice], this is almost
exactly what I typically type.

However, I’d really put ( ) around the expression.

if (notice = response_status_and_flash.delete(:notice))
flash[:notice] = notice
end

This is a trick from JSLint which will complain about assignments in
the conditional expression of an if, but an extra pair of parentheses
will signal your intent and silence the warning.

-Rob

Rob B.
[email protected] http://AgileConsultingLLC.com/
[email protected] http://GaslightSoftware.com/

if notice = response_status_and_flash.delete(:notice)
flash[:notice] = notice
end

This is a common C idiom.

The best solution is to always write your == with the constant on the
LEFT
instead
of the right.

:smiley:


make haste slowly
festina lente \

mobile +1_415_632_6001
[email protected] [email protected]
http://robotarmyma.de

On Fri, May 20, 2011 at 4:23 PM, Rob B.
[email protected]wrote:

instead

end

This is definitely understandable without surprise, while I for sure did
a
double take before understanding Kai’s initial example.