Drying a ternary condition

M

Marcello Barnaba

How would you write the following statement:

klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)

?

Thanks :)
 
T

Tim Pease

How would you write the following statement:

klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)


ARGV[0] ? klass.send:)up) : klass.send:)down)


Blessings,
TwP
 
R

Rob Biedenharn

How would you write the following statement:

klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)

ARGV[0] ? klass.send:)up) : klass.send:)down)

Blessings,
TwP
klass.send(ARGV[0] ? :up : :down)

Since neither of those does the same as the OP's statement, they
can't be right. I'd argue that the statement is pretty DRY already.
Your original code says: "If the first argument is "up" or false,
call klass.up, otherwise call klass.down"

The other responders would call klass.down when ARGV[0] is false/
nil. Also you can't call nil.to_sym (as you probably learned from
ARGV[0].to_sym raising a NoMethodError) or "".to_sym (ArgumentError
for the empty string).

If there were more than two options, something like this might be
helpful.
m=Hash.new:)down).merge!({:up=>:up}) => {:up=>:up}
[ :up, :down, nil, :fred, "up", "down", "", "fred" ].each do |x| ?> puts "#{x.inspect} => #{m[(x.to_sym rescue :up)].inspect}"
end
:up => :up
:down => :down
nil => :up
:fred => :down
"up" => :up
"down" => :down
"" => :up
"fred" => :down
=> [:up, :down, nil, :fred, "up", "down", "", "fred"]

So:

klass.send(Hash.new:)down).merge!({:up=>:up})[(ARGV[0].to_sym
rescue :up)])

Yuck! Stick with the simple ternary for your statement (although you
might want to use the rescue trick instead of just ||).

-Rob

Rob Biedenharn http://agileconsultingllc.com
(e-mail address removed)
 
R

Robert Klemme

How would you write the following statement:

klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)

The only idea I have so far is longer but less complex structured IMHO:

klass.send( case ARGV[0] when "up", nil then :up else :down end )

This one is even better:

klass.send( ARGV[0] || "up" == "up" ? :up : :down )

Dunno what you like more...

robert
 
M

Marcello Barnaba

Hi,

How would you write the following statement:

klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)
The only idea I have so far is longer but less complex structured IMHO:
klass.send( case ARGV[0] when "up", nil then :up else :down end )

I like it: i was trying to achieve the same semantics with fewer :up symbols.
Furthermore, avoiding the ?: operator is an added benefit for readability.

thank you
 
C

ChrisH

How would you write the following statement:

klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)

?

Thanks :)

def upOrdown(a)
a ||= 'up'
if a == 'up'
:up
else
:down
end
end
....
klass.send(upOrdown(ARGV[0]))

Cheers
Chris
 
M

Marcello Barnaba

Hi,

The other responders would call klass.down when ARGV[0] is false/
nil. Also you can't call nil.to_sym (as you probably learned from
ARGV[0].to_sym raising a NoMethodError) or "".to_sym (ArgumentError
for the empty string).

yup :) exactly. thanks for pointing this out.
klass.send(Hash.new:)down).merge!({:up=3D>:up})[(ARGV[0].to_sym =A0
rescue :up)])
Yuck! =A0Stick with the simple ternary for your statement (although you= =A0
might want to use the rescue trick instead of just ||).

that's right, with the rescue i'll be sure that even when some not nil? o=
bject=20
that doesn't respond_to?:)to_sym) is passed, no exception is being raised=
=20

but i'll go with Robert's `case', because it doesn't send to_sym, has jus=
t two=20
`up' in a row, and it doesn't use the (heavily abused by myself in the pa=
st,=20
i feel guilty) ternary operator.

:)
--=20
pub 1024D/8D2787EF 723C 7CA3 3C19 2ACE 6E20 9CC1 9956 EB3C 8D27 87EF
 
D

Devin Mullins

Marcello said:
How would you write the following statement:
klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)
?
klass.send(%w{up down}.find:)up) {|dir| dir == ARGV[0]})

The only way I can think of to get rid of the second 'up' is to
introduce an abstraction. It provides an additional piece of information
-- which one's the default. So:

dirs = %w{up down}
klass.send(dirs.find(dirs.first) {|dir| dir == ARGV[0] })

Devin
 
M

Marcello Barnaba

Hi,

Marcello said:
klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)
klass.send(%w{up down}.find:)up) {|dir| dir == ARGV[0]})

The only way I can think of to get rid of the second 'up' is to
introduce an abstraction. It provides an additional piece of information
-- which one's the default. So:
dirs = %w{up down}
klass.send(dirs.find(dirs.first) {|dir| dir == ARGV[0] })

clever use of .first (setting the default) and .find.

but I think that readability hit a regression.. and first we stood in front of
3 ups, now we stand in front of 4 dirs! :)
 
D

Devin Mullins

Marcello said:
dirs = %w{up down}
klass.send(dirs.find(dirs.first) {|dir| dir == ARGV[0] })

clever use of .first (setting the default) and .find.
well, it turns out, not so clever. i got the api wrong - find expects
the arg to be a Proc. (also there's a typo in the above.) meh:
klass.send(%w{up down}.grep(ARGV[0])[0] || 'up')
readability? what's that?
but I think that readability hit a regression.. and first we stood in front of
3 ups, now we stand in front of 4 dirs! :)

Well, it's likely the wrong place for the code, but while we're hunting
for [what is probably more textual duplication than duplication of
knowledge]:

module Enumerable
def match_or_first(obj)
self[index(obj) || 0]
end
end

klass.send(%w{up down}.match_or_first(ARGV[0])

Don't like the duplicated 'obj'?

Class.new(Array) {
def index(*a)
self[super || 0]
end

klass.send(new(%w{up down}).index(ARGV[0]))
}

Now I just to find a way to factor out the duplicated 'new' and '0'...

Devin
 
A

ara.t.howard

How would you write the following statement:

klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)

?

Thanks :)

i would just do this

klass.send( ARGV[0] || 'up' )

and live with the exception, which will no less clear than

program.rb UP

sending the msg ':down' silently

regards.

-a
 
M

Marcello Barnaba

Hi,

How would you write the following statement:

klass.send((ARGV[0] || :up).to_sym == :up ? :up : :down)
i would just do this

klass.send( ARGV[0] || 'up' )

and live with the exception, which will no less clear than

program.rb UP

sending the msg ':down' silently

that's absolutely right, I didn't even think about that.

thank you.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,234
Messages
2,571,178
Members
47,809
Latest member
Adisty

Latest Threads

Top