1

我正在定义一些新方法String。我需要确保这些方法与其他库中定义的方法不冲突(作为参考,我创建了一个变形器,然后添加了and pluralize)。singularizeString

我的第一个想法是将新东西包装在一个模块中,如下所示:

module MM
  class String
    def rev
      self.split('').reverse.join('')
    end
  end
end

class Test
  include MM

  def me(s)
    s.rev
  end
end

puts Test.new.me('this is a test')

但这当然行不通。String#rev仍然未定义。我的代码中真正拥有的是一个模块MM,除了内置类型扩展之外的所有内容都包含在MM. 我的目标是拥有类似的String方法rev,但仅限于该模块内部,.singularizepluralizeMM

这似乎应该是可行的。但不知何故,我错过了让它如此的秘密咒语。

如果有人可以提供一些建议,将不胜感激。

4

4 回答 4

2

您正在寻找“改进”。它们是 Ruby 2.0 中的一个实验性功能,所以如果您不使用 2.0,您可能会不走运。我自己还没有使用它们,但是您的示例几乎是改进的规范用例。使用refineandusing关键字来获得你想要的行为:

module MM
  refine class String
    def rev
      self.split('').reverse.join('')
    end
  end
end

class Test
  using MM

  def me(s)
    s.rev
  end
end

puts Test.new.me('this is a test')
于 2013-03-05T23:24:51.913 回答
2

缺乏改进,您可以扩展单个字符串对象:

module StringHelper
  def rev
    self.split('').reverse.join('')
  end
end

class Test
  def me(s)
    s.extend(StringHelper).rev
  end
end

或子类字符串:

class StringPlus < String
  def rev
    self.split('').reverse.join('')
  end
  def self.[](s)
    new(s)
  end
end

class Test
  def me(s)
    StringPlus[s].rev
  end
end
于 2013-03-06T01:11:22.747 回答
0

那么还有另一种方法可以让你的字符串类分开。在您添加 require 之前,它将不受任何限制。

#my_string.rb
class String
  def rev
      self.split('').reverse.join('')
   end
end

#test.rb
class Test
  require 'F:\on going\New Site\Ruby\my_string.rb' # Assuming both these files are in the same folder


  def me(s)
    s.rev
  end
end


puts Test.new.me('this is a test')
于 2013-03-05T22:34:55.633 回答
0

作为没有改进的解决方法,我发现这种事情有效:

# class String
#   def rev
#     puts "rev: #{self}"
#   end
# end

class String
  unless String.instance_methods.include?(:rev)
    def rev
      self.split('').reverse.join('')
    end
  end
end

class Test
  def me(s)
    s.rev
  end
end

puts Test.new.me('this is a test')

如果您取消注释它的早期定义,rev它将被尊重而不是被覆盖。这有点 hacky 并且依赖于文件加载的顺序,但如果加载顺序受到控制,它确实可以工作。

于 2013-03-06T19:08:02.200 回答