当我创建一个新对象时,它似乎有一个“值”,例如驻留在哈希中的表示:
h = { str: String.new("asd") } # => {:str=>"asd"}
或者只是在irb:
String.new("asd")
=> "asd"
这是怎么做的?这是什么“asd”?
当我创建自己的课程时:
class A; def initalize(varl); end; end;
a = A.new("asd")
=> #<A:0x007fab7c2fe250>
那是什么 ”#”?我想要的是散列中的一个对象,例如,它的行为就像一个字符串。像这样:
hash = {str: A.new("asd")}
hash[:str] # => "asd"
hash[:str].my_method
我怎样才能做到这一点?我不想从 String 继承。我也想对其他具有其他表示的其他类型执行此操作。
更新:
我真正想做的是构建一个哈希,其中键和值是“某种”整数、字符串和数组,但有我自己定义的方法:
hash = {a: MyArray.new([:x,:y]), b: MyString.new("asdasd")}
hash[:a] # => [:x,:y]
hash[:b] # => "asdasd"
hash[:b].my_method
实际上,对于 ActiveRecord,散列应该是可序列化的。
//编辑:我发现了我真正搜索的内容:
一般没有“价值”。我在我的问题中寻找的是对象在某些方法方面的行为。
如果我想让任何一般对象表现得“像一个数组”,在我的脑海里我想到了一些事情: - 通过 array[] 和 array << entry 和 array.push(entry) 或 array.map{block 访问内容}。
而且我发现仅从 Array 继承是非常糟糕的。更好的方法是使用可转发并将这些方法转发到该对象的属性。
例如:
class Answer::Array
attr_accessor :value
extend Forwardable
def_delegator :@value, :inspect
def_delegator :@value, :to_s
def_delegator :@value, :[]
def_delegator :@value, :[]=
def_delegator :@value, :each
def_delegator :@value, :map
def initlialize
@value = []
end
def my_method
some_code
end
end
因此,要让对象表现得像任何其他“原始”对象,只需使用 Forwardable 将方法委托给值对象即可。