0

当我创建一个新对象时,它似乎有一个“值”,例如驻留在哈希中的表示:

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 将方法委托给值对象即可。

4

3 回答 3

4

字符串表示来自名为 的方法inspect,该方法以字符串格式表示您的对象。

class A
  def initialize(varl)
    @varl = varl
  end
  def inspect
    "An instance of A containing #{@varl.inspect}"
  end
end

A.new "abc"         # => An instance of A containing "abc"
{key: A.new("abc")} # => {:key=>An instance of A containing "abc"}

class A
  def inspect
    @varl.inspect
  end
end
a = A.new "abc"
a # => "abc"
于 2013-08-22T18:21:46.137 回答
0

ruby 中对象的“价值”是什么?

这取决于对象。在定义类时定义它。irb 在每条语句之后显示的不是对象的“值”。它是结果对象的字符串表示形式。

这是什么“asd”?

它是object .to_s 的结果,其中object是您最后一条语句的结果对象。对象是一个抽象的概念,为了展示它,需要将它转换为你可以看到的东西,在这种情况下是一个字符串。是 irb 将对象转换为字符串(通过 to_s 方法),以便您可以看到和理解它。

那是什么 ”#”?

您的新类没有自己的 to_s 方法,并且调用了其中一个祖先的 to_s 方法。我认为是 Module 类,它返回“#< class-name :*pointer-to-the-object*>”

我想要的是散列中的一个对象,它的行为就像一个字符串。我怎样才能做到这一点?

在你的类中定义 to_s 方法。

于 2013-08-22T17:44:03.820 回答
0

#to_s我相信当你这样做时它只是在对象上被调用h[:str]

你可以用你自己的类来模拟这个:

1.9.3p392 :012 > class A
1.9.3p392 :013?>   attr_accessor :varl
1.9.3p392 :014?>   def initialize(varl)
1.9.3p392 :015?>     self.varl = varl
1.9.3p392 :016?>   end
1.9.3p392 :017?>   def to_s
1.9.3p392 :018?>     varl
1.9.3p392 :019?>   end
1.9.3p392 :020?> end
 => nil 
1.9.3p392 :021 > h = {str: A.new("asd") }
 => {:str=>asd} 
1.9.3p392 :023 > h[:str]
 => asd 
于 2013-08-22T16:32:14.347 回答