Ruby 2.4

OpenStruct

class OpenStruct

Parent:Object

OpenStruct是一个类似于Hash的数据结构,允许定义任意属性及其伴随的值。这是通过使用Ruby的元编程来定义类本身的方法来实现的。

例子:

require 'ostruct' person = OpenStruct.new person.name = "John Smith" person.age = 70 person.pension = 300 puts person.name # -> "John Smith" puts person.age # -> 70 puts person.address # -> nil

OpenStruct在内部使用Hash来存储方法和值,甚至可以用一个来初始化:

australia = OpenStruct.new(:country => "Australia", :population => 20_000_000) p australia # -> <OpenStruct country="Australia" population=20000000>

具有空格或字符的散列键通常不能用于方法调用(例如()[] *),并不会立即作为检索或赋值的方法在OpenStruct对象上使用,但仍可通过对象#发送方法。

measurements = OpenStruct.new("length (in inches)" => 24) measurements.send("length (in inches)") # -> 24 data_point = OpenStruct.new(:queued? => true) data_point.queued? # -> true data_point.send("queued?=",false) data_point.queued? # -> false

除去方法的存在需要执行#delete_field方法,因为将属性值设置为nil不会删除该方法。

first_pet = OpenStruct.new(:name => 'Rowdy', :owner => 'John Smith') first_pet.owner = nil second_pet = OpenStruct.new(:name => 'Rowdy') first_pet == second_pet # -> false first_pet.delete_field(:owner) first_pet == second_pet # -> true

执行:

OpenStruct使用Ruby的方法查找结构来查找和定义属性的必要方法。这是通过method_missing和define_method方法完成的。

如果担心创建的对象的性能,这应该是一个考虑因素,因为与使用散列或结构相比,设置这些属性的开销要多得多。

Public Class Methods

json_create(object) Show source

通过构造具有t序列化值的新结构对象来反序列化JSON字符串to_json

# File ext/json/lib/json/add/ostruct.rb, line 11 def self.json_create(object) new(object['t'] || object[:t]) end

new(hash=nil) Show source

创建一个新的OpenStruct对象。默认情况下,生成的OpenStruct对象将没有属性。

可选的hash,如果给出的话,将会生成属性和值(可以是Hash,OpenStruct或Struct)。例如:

require 'ostruct' hash = { "country" => "Australia", :population => 20_000_000 } data = OpenStruct.new(hash) p data # -> <OpenStruct country="Australia" population=20000000>

# File lib/ostruct.rb, line 91 def initialize(hash=nil) @table = {} if hash hash.each_pair do |k, v| k = k.to_sym @table[k] = v end end end

公共实例方法

==(other) Show source

比较这个对象和other平等。OpenStruct等于other什么时候other是OpenStruct,并且两个对象的哈希表是相等的。

# File lib/ostruct.rb, line 311 def ==(other) return false unless other.kind_of?(OpenStruct) @table == other.table! end

显示来源

返回成员的值。

person = OpenStruct.new('name' => 'John Smith', 'age' => 70) person[:age] # => 70, same as ostruct.age

# File lib/ostruct.rb, line 220 def [](name) @table[name.to_sym] end

[]=(name, value) Show source

设置成员的值。

person = OpenStruct.new('name' => 'John Smith', 'age' => 70) person[:age] = 42 # => equivalent to ostruct.age = 42 person.age # => 42

# File lib/ostruct.rb, line 231 def []=(name, value) modifiable?[new_ostruct_member!(name)] = value end

as_json(*) Show source

返回一个散列,它将变成一个JSON对象并表示这个对象。

# File ext/json/lib/json/add/ostruct.rb, line 17 def as_json(*) klass = self.class.name klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!" { JSON.create_id => klass, 't' => table, } end

delete_field(name) Show source

从对象中删除命名的字段。返回字段包含的值,如果它已被定义。

require 'ostruct' person = OpenStruct.new('name' => 'John Smith', 'age' => 70) person.delete_field('name') # => 'John Smith'

# File lib/ostruct.rb, line 263 def delete_field(name) sym = name.to_sym begin singleton_class.__send__(:remove_method, sym, "#{sym}=") rescue NameError end @table.delete(sym) do raise NameError.new("no field `#{sym}' in #{self}", sym) end end

dig(name, *names) Show source

name重复检索与每个对象相对应的值对象。

address = OpenStruct.new('city' => "Anytown NC", 'zip' => 12345) person = OpenStruct.new('name' => 'John Smith', 'address' => address) person.dig(:address, 'zip') # => 12345 person.dig(:business_address, 'zip') # => nil

# File lib/ostruct.rb, line 244 def dig(name, *names) begin name = name.to_sym rescue NoMethodError raise TypeError, "#{name} is not a symbol nor a string" end @table.dig(name, *names) end

each_pair() { |p| ... } Show source

如果未给出块,则产生所有属性​​(作为符号)以及相应的值或返回枚举器。例:

require 'ostruct' data = OpenStruct.new("country" => "Australia", :population => 20_000_000) data.each_pair.to_a # => [[:country, "Australia"], [:population, 20000000]]

# File lib/ostruct.rb, line 129 def each_pair return to_enum(__method__) { @table.size } unless block_given? @table.each_pair{|p| yield p} self end

eql?(other) Show source

比较这个对象和other平等。OpenStruct是eql?到other什么时候other是OpenStruct和两个对象的哈希表是eql ?.

# File lib/ostruct.rb, line 321 def eql?(other) return false unless other.kind_of?(OpenStruct) @table.eql?(other.table!) end

freeze() Show source

调用超类方法Object#freeze

# File lib/ostruct.rb, line 186 def freeze @table.each_key {|key| new_ostruct_member!(key)} super end

hash() Show source

计算这个OpenStruct的散列码。两个具有相同内容的散列将具有相同的散列码(并且将是eql?)。

# File lib/ostruct.rb, line 329 def hash @table.hash end

initialize_copy(orig) Show source

复制一个OpenStruct对象成员。

调用超类方法

# File lib/ostruct.rb, line 102 def initialize_copy(orig) super @table = @table.dup end

inspect() Show source

返回一个字符串,其中包含键和值的详细摘要。

# File lib/ostruct.rb, line 279 def inspect str = "#<#{self.class}" ids = (Thread.current[InspectKey] ||= []) if ids.include?(object_id) return str << ' ...>' end ids << object_id begin first = true for k,v in @table str << "," unless first first = false str << " #{k}=#{v.inspect}" end return str << '>' ensure ids.pop end end

另外别名为:to_s

marshal_dump() Show source

提供编组支持以供元帅图书馆使用。

# File lib/ostruct.rb, line 138 def marshal_dump @table end

marshal_load(x) Show source

提供编组支持以供元帅图书馆使用。

# File lib/ostruct.rb, line 145 def marshal_load(x) @table = x end

respond_to_missing?(mid, include_private = false) Show source

调用超类方法Object#respond_to_missing?

# File lib/ostruct.rb, line 191 def respond_to_missing?(mid, include_private = false) mname = mid.to_s.chomp("=").to_sym @table.key?(mname) || super end

to_h() Show source

使用表示每个属性(作为符号)和它们对应的值的键将OpenStruct转换为散列。示例:

require 'ostruct' data = OpenStruct.new("country" => "Australia", :population => 20_000_000) data.to_h # => {:country => "Australia", :population => 20000000 }

# File lib/ostruct.rb, line 116 def to_h @table.dup end

to_json(*args) Show source

将此结构的值存储为类名(OpenStruct)v作为JSON字符串。

# File ext/json/lib/json/add/ostruct.rb, line 28 def to_json(*args) as_json.to_json(*args) end

to_s()

别名为:检查