I was looking through some code in a string escape library the other day and I came across some code that looks like this:
class StringWrapper
class << self
alias new_no_dup new
def new(str)
开发者_StackOverflow社区 new_no_dup(str.dup)
end
end
def initialize(str)
@str = str
end
...
end
Can anyone explain exactly what is going on here? I understand up to the class << self part, but I don't quite understand aliasing the method new to new_no_dup, only to call it in the new method below? Also, why do you think the author want to do this in this manner?
By aliasing new_no_dup to new, the original new functionality can be called by calling new_no_dup.
The StringWrapper.new method calls duplicate (.dup) on the provided string and then provides that copy to the original StringWrapper.new method.
As for why, I would assume the author is trying to prevent the original string from being changed. StringWrapper will always have it's own string in memory.
Whether you use .dup
on strings influences whether in-place modifications (methods ending with !
) affect the original string.
As a silly little demonstration...
irb(main):009:0> def shout(s)
irb(main):010:1> local = s.dup
irb(main):011:1> local.upcase!
irb(main):012:1> puts local
irb(main):013:1> end
=> nil
irb(main):014:0> greeting = "hi"
=> "hi"
irb(main):015:0> shout(greeting)
HI
=> nil
irb(main):016:0> greeting
=> "hi"
If you run the same snippet, changing local = s.dup
to local = s
, then the final value of greeting
will be "HI"
because shout
will have modified greeting
. .dup
returns a copy of the original string, preventing modifications to the original.
精彩评论