sub vs sub!

Posted by Matt Williams

sub does not do the same thing as sub!:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

irb(main):001:0> a="something"
=> "something"
irb(main):002:0> b=a.sub(/e/,"E")
=> "somEthing"
irb(main):003:0> b
=> "somEthing"
irb(main):004:0> a
=> "something"
irb(main):005:0> c=a.sub!(/thing/,"one")
=> "someone"
irb(main):006:0> c
=> "someone"
irb(main):007:0> a
=> "someone"
irb(main):008:0> b=a.sub(/thing/,"body")
=> "someone"
irb(main):009:0> b
=> "someone"
irb(main):010:0> c=a.sub!(/thing/,"body")
=> nil

They behave the same when there is a pattern matched and a change, however, when there is not a pattern matched they behave differently. This can cause grief as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13

irb(main):011:0> a="something"
=> "something"
irb(main):012:0> b=a.tr("n-za-m","a-z")
=> "fbzrguvat"
irb(main):013:0> b=a.sub(/thing/,"one").tr("n-za-m","a-z")
=> "fbzrbar"
irb(main):014:0> a
=> "something"
irb(main):015:0> b=a.sub!(/body/,"one").tr("n-za-m","a-z")
NoMethodError: undefined method `tr' for nil:NilClass
        from (irb):15
        from :0

This is the general behaviour of any method ending in !, so be careful when you are using them.

Comments

Leave a response