Skip to content

Instantly share code, notes, and snippets.

@charlietanksley
Created October 15, 2011 17:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save charlietanksley/1289870 to your computer and use it in GitHub Desktop.
Save charlietanksley/1289870 to your computer and use it in GitHub Desktop.
Rubinius, MRI 1.8, and MRI 1.9 String#squeeze and String#squeeze! specs

The behavior of String#squeeze and String#squeeze! changes from 1.8 to 1.9. You can see the difference in the two code samples below.

irb(main):009:0> `ruby -v`
=> "ruby 1.8.7 (2011-06-30 patchlevel 352) [i686-darwin11.1.0]\n"
irb(main):010:0> s = '--subbookkeeper--'
=> "--subbookkeeper--"
irb(main):011:0> s.squeeze 'z-a'
=> "--subbookkeeper--"
irb(main):012:0> s.squeeze! 'z-a'
=> nil
irb(main):001:0> `ruby -v`
=> "ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.1.0]\n"
irb(main):002:0> s = '--subbookkeeper--'
=> "--subbookkeeper--"
irb(main):003:0> s.squeeze 'z-a'
ArgumentError: invalid range "z-a" in string transliteration
    from (irb):3:in `squeeze'
    from (irb):3
    from /Users/charlietanksley/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'
irb(main):004:0> s.squeeze! 'z-a'
ArgumentError: invalid range "z-a" in string transliteration
    from (irb):4:in `squeeze!'
    from (irb):4
    from /Users/charlietanksley/.rbenv/versions/1.9.2-p290/bin/irb:12:in `<main>'

Rubinius, of course, works like 1.8:

irb(main):008:0> `ruby -v`
=> "rubinius 1.2.4 (1.8.7 release 2011-07-05 JI) [x86_64-apple-darwin11.1.0]\n"
irb(main):009:0> s = '--subbookkeeper--'
=> "--subbookkeeper--"
irb(main):010:0> s.squeeze 'z-a'
=> "--subbookkeeper--"
irb(main):011:0> s.squeeze! 'z-a'
=> nil
irb(main):004:0> `ruby -v`
=> "rubinius 2.0.0dev (1.8.7 6d095fd3 yyyy-mm-dd JI) [x86_64-apple-darwin11.1.0]\n"
irb(main):005:0> s.squeeze 'z-a'
=> "--subbookkeeper--"
irb(main):006:0> s.squeeze! 'z-a'
=> nil

Now here is the puzzling thing. I added a pair of specs to make sure String#squeeze! worked right in 1.8 and 1.9:

ruby_version_is "1.8" ... "1.9" do
  it "returns nil when the parameter is out of sequence" do
    s = "--subbookkeeper--"
    s.squeeze!("e-b").should == nil
    s.squeeze!("^e-b").should == nil
  end
end

ruby_version_is "1.9" do
  it "raises an error when the parameter is out of sequence" do
    s = "--subbookkeeper--"
    lambda { s.squeeze!("e-b") }.should raise_error(ArgumentError)
    lambda { s.squeeze!("^e-b") }.should raise_error(ArgumentError)
  end
end

The 1.9 test passes, as it should:

$ bin/mspec -tx19 spec/ruby/core/string/squeeze_spec.rb 
rubinius 2.0.0dev (1.9.2 9fe902c0 yyyy-mm-dd JI) [x86_64-apple-darwin11.1.0]
.............

Finished in 0.143006 seconds

1 file, 13 examples, 48 expectations, 0 failures, 0 errors

But the 1.8 test fails:

$ bin/mspec spec/ruby/core/string/squeeze_spec.rb 
rubinius 2.0.0dev (1.8.7 9fe902c0 yyyy-mm-dd JI) [x86_64-apple-darwin11.1.0]
...........F.

1)
String#squeeze! returns nil when the parameter is out of sequence FAILED
Expected "-subokeper-"
 to equal nil

                                     /expectations.rb:15
          { } in Object#__script__ at spec/ruby/core/string/squeeze_spec.rb:111
      Kernel(Object)#instance_eval at kernel/common/eval18.rb:43
     { } in Enumerable(Array)#all? at kernel/common/enumerable.rb:235
                        Array#each at kernel/bootstrap/array.rb:66
            Enumerable(Array)#all? at kernel/common/enumerable.rb:235
                        Array#each at kernel/bootstrap/array.rb:66
                 Object#__script__ at spec/ruby/core/string/squeeze_spec.rb:93
                       Kernel.load at kernel/common/kernel.rb:687
      Kernel(Object)#instance_eval at kernel/common/eval18.rb:43
                        Array#each at kernel/bootstrap/array.rb:66
  Rubinius::CodeLoader#load_script at kernel/delta/codeloader.rb:65
  Rubinius::CodeLoader.load_script at kernel/delta/codeloader.rb:107
           Rubinius::Loader#script at kernel/loader.rb:618
             Rubinius::Loader#main at kernel/loader.rb:772

Finished in 0.076269 seconds

1 file, 13 examples, 48 expectations, 1 failure, 0 errors

So in irb '--subbookkeeper--'.squeeze! 'z-a' returns nil, as it should. But in the test it returns "-subokeper-". This is doubly confusing to me because the spec for 1.8 says the non-bang String#squeeze with a backward range should simply return the string with no changes, and that test passes, even though the bang method is used to define the non-bang method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment