从头开始在 Ruby 中创建修改后的 capitalize 方法

Creating a modified capitalize method in Ruby from scratch

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

  1. 我不知道 capitalize 方法是什么样的
  2. 我的解决方案(它比原来的方法做的更多)似乎可以重构为更优雅的东西。

这是我想出的:

# 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"

开头,只要打印第二个大写字母,它就不需要接近我的解决方案

此外,如果有人能告诉我在哪里可以找到内置大写方法的代码,那也太好了!

提前致谢!

首先,在我看来,除了将字符串的第一个字母大写之外,做任何其他事情都应该是不同的方法或您传递的可选参数。其次,如果你想模仿核心库的行为,你可以用 monkey-patch String.

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

好的,怎么样:

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