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()
别名为:检查