下面的代码片段会返回一个对象。
Brute Force.cpp
class Person
def initialize(name, gender)
@name = name
@gender = gender
end
end
x = Person.new("Dan", "M")
=> #<Person:0x007f6f96600560 @name="Dan", @gender="M">
和哈希< ... >
之间有什么区别?为什么Ruby类不会返回哈希? { ... }
是什么?我很确定它不是0x007f6f96600560
。答案 0 :(得分:1)
当然,有时你可以使用对象和哈希来做同样的事情。存储键值对ob对象,如下所示:
[3] pry(main)> class Person
def initialize(name, gender)
@name = name
@gender = gender
end
end
[3] pry(main)* => :initialize
[4] pry(main)> x = Person.new("Dan", "M")
=> #<Person:0x00000003708098 @gender="M", @name="Dan">
[13] pry(main)> y = Person.new("Peter", "M")
=> #<Person:0x0000000391fca0 @gender="M", @name="Peter">
[22] pry(main)> z = {name: "Maria", gender: "F"}
=> {:name=>"Maria", :gender=>"F"}
但是这些对象实际上并没有从class/object和hash的定义中获得对象定向编程语言的所有功能:
Ruby是一种完美的面向对象编程语言。特点 面向对象编程语言包括:
Data Encapsulation: Data Abstraction: Polymorphism: Inheritance:
这些功能已在面向对象的Ruby中讨论过。
面向对象的程序涉及类和对象。一堂课是 创建单个对象的蓝图。在 面向对象的术语,我们说你的自行车是一个实例 被称为自行车的一类物体。
以任何车辆为例。它包括轮子,马力和 燃料或油箱容量。这些特征构成了数据成员 车辆类。您可以将一辆车与另一辆车区分开来 在这些特征的帮助下。
车辆也可以具有某些功能,例如停车,驾驶, 和超速。甚至这些函数也构成了类的数据成员 车辆。因此,您可以将类定义为组合 特点和功能。
和哈希:
Hash是一组键值对,如下所示:&#34; employee&#34; =&GT; &#34;工资&#34 ;.它类似于一个数组,除了索引是通过 任意对象类型的任意键,而不是整数索引。
因此,对于商店数据,我建议您使用哈希。
另一方面,如注释中所示,对象表示中出现的数字是对象ID,但添加的操作很少:
1)按位左移:
5 << 1 # gives 10
2)传递给hexadeimal
(10).to_s(16)
"a"
pry(main)> x = Person.new("Dan", "M")
=> #<Person:0x00000003708098 @gender="M", @name="Dan">
[5] pry(main)> x.object_id
=> 28852300
[8] pry(main)> (x.object_id << 1 ).to_s(16)
=> "3708098"
最后在ruby中你可以得到像这样的对象的哈希表示:
x.instance_variables.each {|var| hash[var.to_s.delete("@")] = x.instance_variable_get(var) }
答案 1 :(得分:1)
来自Pat Shaughnessy的优秀书籍"Ruby under the microscope":
每个Ruby对象都是类指针和数组的组合 实例变量。
Here描述的时间稍长:
用户定义的Ruby对象由名为an的结构表示 RObject,由名为VALUE的指针引用。
在RObject内部,还有另一个名为RBasic的结构 Ruby值将具有。
除了RBasic结构之外,RObject还包含numiv,一个计数 对象有多少个实例变量,ivptr,一个指针 实例变量的值数组,以及iv_index_tbl 指向存储在对象的关联RClass中的哈希表的指针 将每个实例变量的名称/标识映射到其的结构 在ivtpr数组中的位置。
从任何Ruby对象,都可以extract a hash of instance variables:
class Object
def instance_variables_hash
Hash[instance_variables.map { |name| [name, instance_variable_get(name)] } ]
end
end
用你的例子:
x.instance_variables_hash
=> {:@name=>"Dan", :@gender=>"M"}
但你不可能从这个哈希值中创建x
,因为你错过了一个重要的信息:什么类是x
的一个实例?
例如,您不会知道可以发送到x
的方法:
class Dog
def initialize(name, gender)
@name = name
@gender = gender
end
def bark
puts "WOOF"
end
end
person = Person.new("Dan", "M")
dog = Dog.new("Dan", "M")
p person.instance_variables_hash
# {:@name=>"Dan", :@gender=>"M"}
p dog.instance_variables_hash == person.instance_variables_hash
# true
person.bark
# undefined method `bark' for #<Person:0x007fb3b20ed658 @name="Dan", @gender="M">
要从inspect字符串中取出object_id:
"0x007f6f96600560".sub('0x','').to_i(16)/2
#=> 70058620486320
然后回来:
"0x" + (70058620486320 * 2).to_s(16).rjust(14,'0')
#=> "0x007f6f96600560"