从头开始在Ruby中创建一个修改过的大写方法

时间:2016-07-21 03:07:24

标签: ruby methods capitalization capitalize

我正在学习Ruby中的方法,并认为学习它们的最佳方法是创建一个已经存在的方法。但是,我遇到了两个问题:

  1. 我不知道大写方法是什么样的
  2. 我的解决方案(它比原始方法做的更多)似乎可以重构为更优雅的东西。
  3. 这就是我的想法:

    # method that capitalizes a word
    def new_capitalize(string)
      if string[0].downcase == "m" && string[1].downcase == "c"
        puts "#{string[0].upcase}#{string[1].downcase}#{string[2].upcase}#{string[3..-1].downcase}"
      else
        puts "#{string[0].upcase}#{string[1..-1].downcase}"
      end
    end
    
    name1 = "ryan"
    name2 = "jane"
    
    new_capitalize(name1) # prints "Ryan"
    new_capitalize(name2) # prints "Jane"
    
    str = "mCnealy"
    puts str.capitalize 
           # prints "Mcnealy"
    
    new_capitalize(str) 
           # prints "McNealy"
    

    似乎我的if语句的第一部分可以变得更有效率。只要它打印第二个大写,如果名称以" mc"

    开头,它就不需要接近我的解决方案。

    此外,如果有人可以指出我可以找到内置大写方法的代码,那也很棒!

    提前谢谢!

2 个答案:

答案 0 :(得分:1)

首先,在我看来,除了大写字符串的第一个字母之外,做任何事情应该是一个不同的方法或你传递的可选arg。其次,如果你试图模仿核心的lib行为而不是猴子补丁字符串。

class String
  def capitalize
    self[0].upcase << self[1..-1].downcase
  end
end

最接近官方ruby实现的可能是Rubinius

https://github.com/rubinius/rubinius/blob/377d5c958bc8239514fb98701b75859c6b51b9d4/core/string.rb#L332

答案 1 :(得分:1)

好吧,怎么样:

module NameRules
  refine String do
    def capitalize
      if self[0..1].downcase == 'mc'
        "Mc#{self[2..-1].capitalize}"
      else
        super
      end
    end
  end
end

然后使用它:

class ThingWithNames
  using NameRules

  def self.test(string)
   string.capitalize
  end
end

ThingWithNames.test('mclemon') # => "McLemon"
ThingWithNames.test('lemon') # => "Lemon"

如果我们从头开始而不使用C实现的代码:

module NameRules
  refine String do
    def capitalize
      if self[0..1].downcase == 'mc'
        "Mc#{self[2..-1].capitalize}"
      else
        new_string = self.downcase
        new_string[0] = new_string[0].upcase
        new_string
      end
    end
  end
end

参考资料:

String#capitalize source
A really good presentation on refinements