Case expressions and LHS of assignment

While trying to avoid Repetition in my code I tried to rewrite a case
statement, thinking how they can be used on the right hand side of an
assignment, so I tried the left hand side. It basically came down to
this:

#!/usr/local/bin/ruby -w

class Lvalue
def initialize
@a = @b = @c = "initial"
end
def assign(x,y)
(case x
when 1
@a
when 2
@b
when 3
@c
end) = y
end
end

lvalue = Lvalue.new
lvalue.assig(2,“Different”)
p lvalue

END
but this gives:

/home/hgs/progs/ruby/lvalue1.rb:15: parse error
end) = y
^

I tried leaving the () off too. I was not really surprised when it
failed, but I was left wondering about it. In an ideal world is this
desirable, or is it complicating things too much? I bet it would
complicate the parser. Is it even sensible?

This might not lead to Repetition, but may lead to Deviation
(http://www.bbc.co.uk/radio4/comedy/justaminute.shtml)!

    Hugh (possibly thinking too far outside the box!)

Perhaps you could use an array to hold you instance variables rather
than the 3 seperate ones. This then gives

def initialize
@values = Array.new
(1…3).times { @value << “Initial” }
end

def assign(x,y)
@values[x] = y
end

Even shorter (especially without error checking :slight_smile: ) and much much clearer.

Hi,

While trying to avoid Repetition in my code I tried to rewrite a case
statement, thinking how they can be used on the right hand side of an
assignment, so I tried the left hand side. It basically came down to
this:

Unlike Perl (nor C++), the evaluated result of case statement is the
"value", not the “reference”. And I feel this is a good thing. Why not

def assign(x,y)
case x
when 1
@a = y
when 2
@b = y
when 3
@c = y
end
end

						matz.
···

In message “Case expressions and LHS of assignment…” on 02/07/10, Hugh Sasse Staff Elec Eng hgs@dmu.ac.uk writes:

You’re taking the contrived, cut-down example too literally :-). The
numbers were easier to type to test this out, I was using symbols in
fact, :x, :y, and :z in the first place, but the problem is more
general than that because a case statement can be used with anything
that copes with ===.

    Thanks anyway :-),
    Hugh
···

On Wed, 10 Jul 2002, Peter Hickman wrote:

Perhaps you could use an array to hold you instance variables rather
than the 3 seperate ones. This then gives

def initialize
@values = Array.new
(1…3).times { @value << “Initial” }
end

def assign(x,y)
@values[x] = y
end

Even shorter (especially without error checking :slight_smile: ) and much much clearer.

Hi,

While trying to avoid Repetition in my code I tried to rewrite a case
statement, thinking how they can be used on the right hand side of an
assignment, so I tried the left hand side. It basically came down to
this:

Unlike Perl (nor C++), the evaluated result of case statement is the
"value", not the “reference”. And I feel this is a good thing. Why not

A good thing because it would lead to tangled code, “giving too much
rope to for the programmer to hang themselves” etc, or some other
reason?

def assign(x,y)
case x
when 1
@a = y
when 2
@b = y
when 3
@c = y
end
end

That is what I did in the end (well, ‘y’ was a big expression, so I used
a temp var to hold it):
t = long_boring_expression
case x
when :one
@a = t
and so on. I was just trying to optimise my code in the direction of
the Don’t Repeat Yourself rule, and wondered how far I could push it.

  					matz.
    Hugh
···

On Wed, 10 Jul 2002, Yukihiro Matsumoto wrote:

In message “Case expressions and LHS of assignment…” > on 02/07/10, Hugh Sasse Staff Elec Eng hgs@dmu.ac.uk writes:

You can still use a similar approach using a hash with symbols as
keys. In the assignment, use the case expression to detemine the
key. Something like

def initialize
@values = Hash.new( “Initial” )
end

def assign( x, y )
@values[
case x
when …
:x
when …
:y
else
:z
end
] = y
end

Regards,
Pit

···

On 10 Jul 2002, at 19:01, Hugh Sasse Staff Elec Eng wrote:

On Wed, 10 Jul 2002, Peter Hickman wrote:

Perhaps you could use an array to hold you instance variables rather
than the 3 seperate ones. This then gives

def initialize
@values = Array.new
(1…3).times { @value << “Initial” }
end

def assign(x,y)
@values[x] = y
end

Even shorter (especially without error checking :slight_smile: ) and much much
clearer.

You’re taking the contrived, cut-down example too literally :-). The
numbers were easier to type to test this out, I was using symbols in
fact, :x, :y, and :z in the first place, but the problem is more
general than that because a case statement can be used with anything
that copes with ===.

Hi,

···

In message “Re: Case expressions and LHS of assignment…” on 02/07/10, Hugh Sasse Staff Elec Eng hgs@dmu.ac.uk writes:

Unlike Perl (nor C++), the evaluated result of case statement is the
"value", not the “reference”. And I feel this is a good thing. Why not

A good thing because it would lead to tangled code, “giving too much
rope to for the programmer to hang themselves” etc, or some other
reason?

Not allowing lhs as a result is good, because of the combination of
the following:

  • it’s too hard to implement.

  • it’s too abusable (too much rope to hang yourself).

  • it makes the language comprecated without helping it much.

    					matz.
    

You’re taking the contrived, cut-down example too literally :-). The
numbers were easier to type to test this out, I was using symbols in
fact, :x, :y, and :z in the first place, but the problem is more
general than that because a case statement can be used with anything
that copes with ===.

You can still use a similar approach using a hash with symbols as
keys. In the assignment, use the case expression to detemine the
key. Something like

def initialize
@values = Hash.new( “Initial” )
end

def assign( x, y )
@values[
case x
when …
:x
when …
:y
else
:z
end
] = y
end

Good point. I like this one. Thank you.

Regards,
Pit

    Hugh
···

On Wed, 10 Jul 2002, Pit Capitain wrote:

On 10 Jul 2002, at 19:01, Hugh Sasse Staff Elec Eng wrote:

On Wed, 10 Jul 2002, Peter Hickman wrote:

A good thing because it would lead to tangled code, “giving too much
rope to for the programmer to hang themselves” etc, or some other
reason?

Not allowing lhs as a result is good, because of the combination of
the following:

  • it’s too hard to implement.
  • it’s too abusable (too much rope to hang yourself).
  • it makes the language comprecated without helping it much.

Yes, I think I’d agree with those. The gain/complexity trade-off is a
very strong case for no change. Thank you for your response.

  					matz.
    Hugh
···

On Wed, 10 Jul 2002, Yukihiro Matsumoto wrote: