如何实现String方法的破坏性版本?

时间:2014-03-21 08:56:12

标签: ruby string

我复制了underscore方法的以下实现,将camel case中的字符串转换为字符串,并用下划线分隔:

class String
  def underscore
    self.gsub(/::/, '/').
    gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
    gsub(/([a-z\d])([A-Z])/,'\1_\2').
    tr("-", "_").
    downcase
  end
end

如何实现一种方法,比如underscore!,以破坏性方式执行相同的操作,即修改字符串?

3 个答案:

答案 0 :(得分:6)

使用String#replace方法:

class String
  def underscore
    # same as before
  end

  def underscore!
    replace(underscore)
  end
end

s = 'FooBar'
s.underscore!
puts s
# 'foo_bar'

答案 1 :(得分:4)

基本上只需用它替换你体内的每一种方法!当量。但是,那么你还需要调整一个事实!如果没有变化,方法应返回nil。例如:

class String
    def underscore!
        if [ self.gsub!(/::/, '/'), 
             self.gsub!(/([A-Z]+)([A-Z][a-z])/,'\1_\2'),
             self.gsub!(/([a-z\d])([A-Z])/,'\1_\2'),
             self.tr!("-", "_"),
             self.downcase!
           ].any?
            self        
        else
            nil
    end
    end
end

答案 2 :(得分:0)

为什么不使用alias_method

class String
  def underscore
    self.gsub(/::/, '/').
    gsub(/([def underscore
    dup.underscore!
  endA-Z]+)([A-Z][a-z])/,'\1_\2').
    gsub(/([a-z\d])([A-Z])/,'\1_\2').
    tr("-", "_").
    downcase
  end

  alias_method :orig_underscore, :underscore

  def underscore!
    self.replace self.orig_underscore
  end
end