Ruby对象与哈希

时间:2017-03-12 05:56:09

标签: ruby

下面的代码片段会返回一个对象。

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

2 个答案:

答案 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/objecthash的定义中获得对象定向编程语言的所有功能:

  

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">

的object_id

要从inspect字符串中取出object_id:

"0x007f6f96600560".sub('0x','').to_i(16)/2
#=> 70058620486320

然后回来:

"0x" + (70058620486320 * 2).to_s(16).rjust(14,'0')
#=> "0x007f6f96600560"