2

Is there a better way to write this?

if a == 'new' || a == 'create'
  ...
else
  ...
end

Instead of checking a twice, I thought I could combine the first line with one a. I'm looking at something like:

if a == ['new' || 'create']
Victor
  • 13,010
  • 18
  • 83
  • 146

2 Answers2

6

It's possible to do the test several ways, but doing it on a single line isn't necessarily the best idea. One of the clearest ways to write it in Ruby is to use a case statement:

case a
when 'new', 'create'
  ...
else
  ...
end

The advantage to doing this is you can easily add additional tests by appending them to the when list.

You could get down and dirty with a regex:

%w[foo renew new created create].each do |w|
  puts w[/^(?:new|create)$/]
end

Which would generate output like:

# >> 
# >> 
# >> new
# >> 
# >> create

# >> is the output marking a new line when using Sublime Text. This means only new and create matched.

I don't especially recommend that unless you understand regular expressions, but it can be an extremely fast way to check against a huge number of options.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
  • 1
    I don't think your second part is helpful. With just the case statement part, your answer will look much better. – sawa Jun 16 '13 at 04:35
  • The second part is extremely helpful when checking against a long list of possible values. The regex engine is much faster than iterating over an array, or using `include`. – the Tin Man Jun 16 '13 at 04:37
  • 1
    @theTinMan out of curiosity would you use a set or a regexp for say 100+ options? – AJcodez Jun 16 '13 at 04:41
  • I've used a regex for well over 100 options. A set can be much faster than an array when searching, because it doesn't take a linear search to find something, since `Set` is basically a hash key -- it might be faster to generate a hash actually. If the target words are static, it's possible to generate a highly optimized regex that I suspect would be highly efficient, so much so I'd have to do a benchmark to see if set was worth using for the same sort of test. http://stackoverflow.com/questions/4002494/whats-the-best-way-to-apply-many-perl-regular-expression-tests/4002558#4002558 – the Tin Man Jun 16 '13 at 04:59
3

yes there is :

if %w(new create).include? a
  #code here
else
  #code
end
Arup Rakshit
  • 116,827
  • 30
  • 260
  • 317
  • 2
    this solution creates an extra object in memory. whereas the code in the original question does not. I personally do not see anything wrong with the original code. – akonsu Jun 16 '13 at 04:32
  • 1
    @akonsu Nothing is *wrong* with it, they were asking for an alternative. – Hunter McMillen Jun 16 '13 at 04:33
  • 1
    @akonsu its not all about performance. @victor you can make it even terser `%w(new create).include? a` – AJcodez Jun 16 '13 at 04:33
  • @AJcodez you make it sound as if the original code is more difficult to maintain. I think it is clearer to understand that the idiom with the array. – akonsu Jun 16 '13 at 04:38
  • 1
    @akonsu to each his/her own for sure. I use `include?` in my ruby code cause its easier on my eyes, and extends well to 3 or 4 options. doesnt matter much either way – AJcodez Jun 16 '13 at 04:45
  • 1
    @AJcodez yes, you are right I modified my code with your `%w(new create).include? a`. that's good. I liked that. – Arup Rakshit Jun 16 '13 at 04:46