4
\$\begingroup\$

Is it possible to shorten this, or to improve the code in any way? I know it's just a simple if-statement, but it's always fun to learn a shorter way of doing things.

if self.citizenship == 'ES'
  @identification_type = IDENTIFICATION_TYPES[0]
elsif self.country == 'ES'
  @identification_type = IDENTIFICATION_TYPES[1]
end
\$\endgroup\$

4 Answers 4

3
\$\begingroup\$

You could remove a little duplication like this:

@identification_type = if self.citizenship == 'ES'
  IDENTIFICATION_TYPES[0]
elsif self.country == 'ES'
  IDENTIFICATION_TYPES[1]
end
\$\endgroup\$
1
  • 2
    \$\begingroup\$ In other words: the way to shorten this if-statement is to realize that is isn't an if-statement, it's an if-expression! In fact, there are no statements in Ruby, everything is an expression. \$\endgroup\$ Commented Dec 30, 2011 at 13:28
0
\$\begingroup\$

I don't know Ruby, so I'm not sure this is at all idiomatic. However, you can do something like this (if you're looking for a one-liner):

@identification_type = IDENT_TYPES[[@citizenship, @country].index('ES')]

Just so this makes some sort of sense (in case I didn't understand your code), here is some context:

IDENT_TYPES = {0 => :citizen, 1 => :country}

class Foo
    attr_accessor = :citizenship, :country, :identification_type

    def initialize(citizenship, country)
        @citizenship = citizenship
        @country = country
        @identification_type = IDENT_TYPES[[@citizenship, @country].index('ES')]
        puts @identification_type
    end
end

foo = Foo.new('ES', 'EN')
foo = Foo.new('EN', 'ES')
foo = Foo.new('EN', 'EN')

This outputs:

citizen
country
nil
\$\endgroup\$
1
  • \$\begingroup\$ Interesting approach, but I don't think this code communicates very well. \$\endgroup\$
    – Torbjørn
    Commented Dec 30, 2011 at 9:10
0
\$\begingroup\$

You could replace the if with case. Normally, the case-statement contains a variable and the when-statements contain constant or variables. But you may do it the other was:

#Some code to make it executable
IDENTIFICATION_TYPES = [1,2]
class MyObject
  def citizenship; 'ES';end
  def country;  'ES';end
  attr_reader :identification_type

  def test
  #The code:
  @identification_type  = case 'ES'
    when self.citizenship
      IDENTIFICATION_TYPES[0]
    when self.country
      IDENTIFICATION_TYPES[1]
    end
  end
end

p MyObject.new.test

Advantage: you don't need to repeat the == 'ES'.

Disadvantage: Mixed checks (ES or AS...) is not possible.

\$\endgroup\$
2
  • \$\begingroup\$ Now things like 1.citizenship and [].country are possible. Don't do this. \$\endgroup\$
    – steenslag
    Commented Dec 30, 2011 at 21:45
  • \$\begingroup\$ The modification of Object was only a quick possibility to make the example executable - it wasn't meant to be 'real' code. In real case, the code should be embedded in a Object.- I adapted the example to avoid a change of Object. \$\endgroup\$
    – knut
    Commented Dec 30, 2011 at 21:59
0
\$\begingroup\$

Based on your code (somewhat like @AdamWagner's answer), here's a way without a case statement (though self.country is always evaluated):

criteria=[self.citizenship, self.country]
@identification_type=
 IDENTIFICATION_TYPES.at criteria.index{|e| 'ES'==e}

And a way with a case statement:

k=case 'ES'
  when self.citizenship then 0
  when self.country     then 1
  end
end
@identification_type=
 IDENTIFICATION_TYPES.at k
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.