Ruby中的符号/字符串可互换对象

时间:2013-01-11 16:52:32

标签: ruby

我需要一个带有字符串或符号的对象(然后将其转换为字符串),并且可以与字符串或符号进行比较,与HashWithIndifferent访问行为的方式类似:

StringWithIndifferentAccess.new("foo").include? :f
=> true

StringWithIndifferentAccess.new(:foo) ==  "foo"
=> true

有没有一种简单的方法可以做到这一点并让它“正常工作”(TM)而无需手动重新定义每个字符串方法?

2 个答案:

答案 0 :(得分:3)

这传递了你的例子

class StringWithIndifferentAccess
  def initialize obj
    @string = obj.to_s
  end

  def == (other)
    @string == other.to_s
  end

  def include?(other)
    @string.include? other.to_s
  end
end

更新

所以我再次阅读这个问题并为所有字符串方法“正常工作”,你可以使用method_missing并将任何符号转换为字符串,如下所示:

class StringWithIndifferentAccess
  def initialize obj
    @string = obj.to_s
  end

  # Seems we have to override the == method because we get it from BasicObject
  def == (other)
    @string == other.to_s
  end

  def method_missing(method, *args, &block)
    args.map! {|arg| arg.is_a?(Symbol) ? arg.to_s : arg }
    if @string.respond_to?(method)
      @string.send(method, *args, &block)
    else
      raise NoMethodError  
    end    
  end
end

答案 1 :(得分:0)

您可以使用:

sym = :try
sym.class
=> Symbol
str = "try"
str.class
=> String
str.to_sym
=> :try
sym.to_s
=> "try"

因此,只需创建一个使用符号或字符串构造的类,但其值也始终为字符串。添加一个undefined方法,它接受一个参数,将其转换为字符串,然后在值上调用它。

希望这会有所帮助。