0

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

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

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

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

4

2 回答 2

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
于 2013-01-11T18:13:18.060 回答
0

你可以使用这个:

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

因此,只需创建一个使用符号或字符串构造但也具有始终为字符串的值的类。添加一个未定义的方法,该方法采用单个参数,将其转换为字符串,然后在值上调用它。

希望这会有所帮助。

于 2013-01-11T16:58:56.867 回答