在方法

时间:2015-07-02 16:42:32

标签: ruby

我希望有一个名为delete_commas的方法删除字符串中的逗号。以下是我的内容:

def delete_commas
  gsub(',','')
end

string = "this string, has, alot, of, commas,,,"

我期待:

string.delete_commas # => "this string has alot of commas"

这不起作用,它会引发错误:

NoMethodError: private method 'delete_commas' called for "this string, has, alot, of, commas,,,":String

我可以这样做:

def delete_commas(string)
  string.gsub(',','')
end
delete_commas(string)

但这不是我想要的方式。想知道我是否能得到一些重构帮助。

我实际上为这个https://github.com/txssseal/delete_commas

创建了一个gem

3 个答案:

答案 0 :(得分:4)

string.delete_commas中定义String类的方法,delete_commas应该是String方法

class String
   def delete_commas
     self.gsub(',','')
   end
end

string = "this string, has, alot, of, commas,,,"

string.delete_commas
# => "this string has alot of commas"

答案 1 :(得分:3)

这样做:

string.delete ","

就是这样。无需重新发明Ruby内置。

答案 2 :(得分:2)

如@Mark Thomas所述,您正在寻找的功能已经成为语言的一部分,使用:

"this string, has, alot, of, commas,,,".delete ","

但是如果你想要添加新的功能,有几种方法可以做到。

查看您想要的代码:

string = "this string, has, alot, of, commas,,,"
string.delete_commas # => "this string has alot of commas"

您必须查看哪些对象正在接收您要发送的邮件。在这种情况下,"this string, has, alot, of, commas,,,"对象是String的实例。为了使该对象响应该消息,String类需要实现该名称的方法,正如@shivam建议的那样。

重要的是要注意这是被亲切地称为monkey patch的东西。这带来了一些缺点,其中一些在我链接的文章中列出。

从Ruby 2.0开始实现这一目标的更安全的方法是Refinements。通过声明一个定义字符串类的细化的模块,您可以准确选择要优化字符串的范围:

module ExtraStringUtils
  refine String do
    def delete_commas
      gsub(',','')
    end
  end
end

class MyApplication
  using ExtraStringUtils

  "this string, has, alot, of, commas,,,".delete_commas
    #=> this string has alot of commas
end

"this string, has, alot, of, commas,,,".delete_commas 
  #=> NoMethodError: undefined method `delete_commas' for "this string, has, alot, of, commas,,,":String

换句话说,无论您身在何处String,都可以访问using ExtraStringUtils的特殊更改,但无处可去。

获得类似结果的最后一种方法是拥有自己的类来实现该方法并在内部对字符串进行操作:

class MySuperSpecialString
  def initialize string
    @string = string
  end

  def delete_commas
    @string.gsub!(',','') #gsub! because we want it to permenantly change the stored string
  end
end

此时的用法是:

string = MySuperSpecialString.new("this string, has, alot, of, commas,,,")
string.delete_commas # => "this string has alot of commas"

这种方法有其特殊的缺点,其中最大的缺点是它不响应字符串的所有方法。您可以使用委托将未知方法传递给字符串,但仍然存在一些接缝,它不会像字符串那样表现得很好,并且它不会像单独的类一样表现,所以请注意返回值。