Case expression different in Ruby 1.9?
There was a change in the syntax between 1.8.x and 1.9.x where the :
is now no longer allowed:
birthyear = 1986
generation = case birthyear
when 1946...1963
"Baby boomer"
when 1964...1976
"Generation X"
when 1977...2012
"new generation"
else
nil
end
puts generation
Technically :
has been replaced by then
but that's an optional keyword if you use a newline. It's a bit of a hassle to go and track down cases where you've used the old syntax, so hopefully searching for case
is close enough.
Difference between == and case?
It looks like a bug in YARV on windows. I get the correct output in JRuby 1.6.0:
# ruby -v
ruby 1.9.2p180 (2011-02-18) [i386-mingw32]
# ruby test.rb
Quote
ErrCase
true
true
"\""
# jruby --1.9 -v
jruby 1.6.0 (ruby 1.9.2 patchlevel 136) (2011-03-15 f3b6154) (Java HotSpot(TM) Client VM 1.7.0-ea) [Windows XP-x86-java]
# jruby --1.9 test.rb
Quote
QuoteCase
true
true
"\""
How to do multiple assignment with return values in ruby (1.9) case statement?
You should be returning array for this. Otherwise it confuses the parser.
limit, pattern = case period_group
when 'day' then [7, 'D']
when 'week' then [7, 'WW']
else ['12','MM']
end
I don't see why you wanted to get rid of square brackets. It's even more readable that way.
Ruby: target-less 'case', compared to 'if'
Midwire ran a few benchmarks and concluded that if/elsif is faster
than case because case “implicitly compares using the more expensive
=== operator”.
Here is where I got this quote. It compares if
/elsif
statements to case
.
It is very thorough and explores the differences in the instruction sequence, definitely will give you an idea on which is better.
The main thing i pulled from the post though, is that both if/else if and case have no huge differences, both can usually be used interchangeably.
Some major differences can present themselves depending on how many cases you have.
n = 1 (last clause matches)
if: 7.4821e-07
threequal_if: 1.6830500000000001e-06
case: 3.9176999999999997e-07
n = 15 (first clause matches)
if: 3.7357000000000003e-07
threequal_if: 5.0263e-07
case: 4.3348e-07
As you can see, if the last clause is matched,if
/elsif
runs much slower than case, while if
the first clause is matched, it's the other way around.
This difference comes from the fact that if
/elsif
uses branchunless
, while case
uses branchif
in their instruction sequences.
Here is a test I did on my own with a target-less case
vs if
/elsif
statements (using "=="). The first time is case
, while the second time is if
/elsif
.
First test, 5 when
statements, 5 if
/elsif
, the first clause is true for both.
Time elapsed 0.052023 milliseconds
Time elapsed 0.031467999999999996 milliseconds
Second test, 5 when
statements, 5 if
/elsif
, the last(5th) clause is true for both.
Time elapsed 0.001224 milliseconds
Time elapsed 0.028578 milliseconds
As you can see, just as we saw before, when the first clause is true, if/elsif perform better than case, while case has a massive performance advantage when the last clause is true.
CONCLUSION
Running more tests has shown that it probably comes down to probability. If you think the answer is going to come earlier in your list of clauses, use if
/elsif
, otherwise case
seems to be faster.
The main thing that this has shown is that both case
and if
/elsif
are equally efficient and that using one over the other comes down to probability and taste.
SyntaxError using Case Expression on Sinatra 1.2.0 and Ruby 1.9.2
The problem is that you can't have arbitrary statements in a case
statement. This is actually a very rare case where ruby limits where you can have code.
The way ERb works is that it inserts statements around your code to which it channels the output. You can see it in your error log. In this case the code that is generated is something like this:
case @status
@_out_buf.concat "\n "
when "foo"
@_out_buf.concat "\n It's a FOO!\n "
when "bar"
@_out_buf.concat "\n It's a BAR!\n "
else
@_out_buf.concat "\n It's something else...!\n "
end
As you see the second line here is what causes the problem. You might be able to solve it is have your ERb suppress the newline concat:
<% case @status; when "foo" %>
or (though this might not work):
<% case @status -%>
<% when "foo" %>
How to write a switch statement in Ruby
Ruby uses the case
expression instead.
case x
when 1..5
"It's between 1 and 5"
when 6
"It's 6"
when "foo", "bar"
"It's either foo or bar"
when String
"You passed a string"
else
"You gave me #{x} -- I have no idea what to do with that."
end
Ruby compares the object in the when
clause with the object in the case
clause using the ===
operator. For example, 1..5 === x
, and not x === 1..5
.
This allows for sophisticated when
clauses as seen above. Ranges, classes and all sorts of things can be tested for rather than just equality.
Unlike switch
statements in many other languages, Ruby’s case
does not have fall-through, so there is no need to end each when
with a break
. You can also specify multiple matches in a single when
clause like when "foo", "bar"
.
How does Ruby 1.9 handle character cases in source code?
I can't get IRB to accept UTF-8 characters, so I used a test script (/tmp/utf_test.rb
).
"λ" works fine as a variable name:
# encoding: UTF-8
λ = 'foo'
puts λ
# from the command line:
> ruby -KU /tmp/utf_test.rb
foo
"λ" also works fine as a method name:
# encoding: UTF-8
Kernel.class_eval do
alias_method :λ, :lambda
end
(λ { puts 'hi' }).call
# from the command line:
> ruby -KU /tmp/utf_test.rb:
hi
It doesn't work as a constant, though:
# encoding: UTF-8
Object.const_set :λ, 'bar'
# from the command line:
> ruby -KU /tmp/utf_test.rb:
utf_test.rb:2:in `const_set': wrong constant name λ (NameError)
Nor does the capitalized version:
# encoding: UTF-8
Object.const_set :Λ, 'bar'
# from the command line:
> ruby -KU /tmp/utf_test.rb:
utf_test.rb:2:in `const_set': wrong constant name Λ (NameError)
My suspicion is that constant names must start with a capital ASCII letter (must match /^[A-Z]/
).
Why doesn't case with when 2 work?
An if
statement would probably be more fitting for your code, since you don't have a definitive range/value, but rather just a greater-than:
if ARGV.length == 0
abort "Error 1"
elsif ARGV.length > 2
abort "Error 2"
end
Ruby 1.9: how can I properly upcase & downcase multibyte strings?
Case conversion is locale dependent and doesn't always round-trip, which is why Ruby 1.9 doesn't cover it (see here and here)
The unicode-util gem should address your needs.
Related Topics
Ruby Create Tar Ball in Chunks to Avoid Out of Memory Error
Ruby: How to Check If a String Contains Multiple Items
How to Change Passenger Ruby Version Without Recompiling
Execjs::Programerror in Welcome#Index Typeerror: Object Doesn't Support This Property or Method
Configuration in Allure to Cucumber in Ruby
Better Way to Write "Matching Balanced Parenthesis" Program in Ruby
Getting Current Line of Code in Ruby
Undefined Method Pluralize for Main:Object
Determine the Class to Which a Method Belongs in Rails
Get an Array from a Rails Form
How to Set Ca-Bundle Path for Openssl in Ruby
How to Delete a Range of Values from an Array
Grouping Consecutive Numbers in an Array
Custom Filtering of Parameters in Rails 3 Using Config.Filter_Parameters
Creating Spectral Heat Maps or Intensity Maps from Cdip Data Using Ruby
Is There a Solution to Bypass 'Can't Add a New Key into Hash During Iteration (Runtimeerror)'
How to Best Handle Per-Model Database Connections with Activerecord