Struct
class Struct
父类:ObjectIncluded模块:Enumerable
Struct是一种使用访问器方法将多个属性捆绑在一起的简便方法,无需编写显式类。
Struct类生成包含一组成员及其值的新子类。对于每个成员,创建一个类似于Module#attr_accessor的读写器方法。
Customer = Struct.new(:name, :address) do
def greeting
"Hello #{name}!"
end
end
dave = Customer.new("Dave", "123 Main")
dave.name #=> "Dave"
dave.greeting #=> "Hello Dave!"
有关创建结构子类和实例的更多示例,请参阅:: new。
在后面的方法描述中,“成员”参数指的是一个结构成员,它是一个带引号的字符串("name"
)或一个符号(:name
)。
常量
组
组
组是一个Struct,只有在编译时才可用HAVE_GETGRENT
。
该结构包含以下成员:
名字
以String形式包含组的名称。
passwd
包含加密密码作为字符串。如果组的密码访问不可用,则返回'x'; 如果不需要密码来获取组的成员资格,则返回空字符串。
必须与编译HAVE_STRUCT_GROUP_GR_PASSWD
。
gid
包含组的数字ID作为整数。
mem
是包含组成员简短登录名的字符串数组。
Passwd
Passwd
Passwd是包含以下成员的Struct:
name
包含用户的短登录名作为字符串。
passwd
包含用户的加密密码作为字符串。如果正在使用阴影密码,则会返回'x'。如果用户无法使用密码登录,则会返回'*'。
uid
包含用户的整数用户ID(uid)。
gid
包含用户主组的整数组ID(gid)。
dir
以String形式包含用户主目录的路径。
shell
包含用户的登录shell的路径作为字符串。
以下成员是可选的,并且必须使用特殊标志进行编译:
gecos
包含用户的更长字符串描述,例如全名。一些Unix系统在gecos领域提供结构化信息,但这是依赖于系统的。必须与编译HAVE_STRUCT_PASSWD_PW_GECOS
change
密码更改时间(整数)必须使用编译 HAVE_STRUCT_PASSWD_PW_CHANGE
quota
配额值(整数)必须用。编译 HAVE_STRUCT_PASSWD_PW_QUOTA
age
密码的年龄(整数)必须用。编译 HAVE_STRUCT_PASSWD_PW_AGE
class
用户访问类(字符串)必须使用编译 HAVE_STRUCT_PASSWD_PW_CLASS
comment
评论(字符串)必须与编译 HAVE_STRUCT_PASSWD_PW_COMMENT
expire
帐户到期时间(整数)必须用。编译 HAVE_STRUCT_PASSWD_PW_EXPIRE
Tms
公共类方法
json_create(object) 显示源
通过构造具有v
序列化值的新结构对象来反序列化JSON字符串to_json
。
# File ext/json/lib/json/add/struct.rb, line 10
def self.json_create(object)
new(*object['v'])
end
new(class_name+) → StructClass 显示源
new(class_name+) {|StructClass| block } → StructClass
new(value, ...) → object
StructClassvalue, ... → object
前两个表单用于创建一个新的Struct子类class_name
,其中可以包含每个值的值member_name
。这个子类可以像任何其他类一样用于创建结构的实例。
如果class_name
省略,则会创建一个匿名结构类。否则,此结构的名称将在类Struct中显示为常量,因此它必须对系统中的所有Structs都是唯一的,并且必须以大写字母开头。给一个常量赋一个结构类也给这个类定义了这个常量的名字。
# Create a structure with a name under Struct
Struct.new("Customer", :name, :address)
#=> Struct::Customer
Struct::Customer.new("Dave", "123 Main")
#=> #<struct Struct::Customer name="Dave", address="123 Main">
# Create a structure named by its constant
Customer = Struct.new(:name, :address)
#=> Customer
Customer.new("Dave", "123 Main")
#=> #<struct Customer name="Dave", address="123 Main">
如果给出了一个块,它将在上下文中进行评估StructClass
,将创建的类作为参数传递:
Customer = Struct.new(:name, :address) do
def greeting
"Hello #{name}!"
end
end
Customer.new("Dave", "123 Main").greeting #=> "Hello Dave!"
这是定制结构的推荐方法。子类化匿名结构会创建一个永远不会被使用的额外的匿名类。
最后两个窗体创建一个结构子类的新实例。value
参数的数量必须小于或等于为结构定义的属性的数量。取消设置参数默认为nil
。传递比属性数量更多的参数会引发ArgumentError。
Customer = Struct.new(:name, :address)
Customer.new("Dave", "123 Main")
#=> #<struct Customer name="Dave", address="123 Main">
Customer["Dave"]
#=> #<struct Customer name="Dave", address=nil>
static VALUE
rb_struct_s_def(int argc, VALUE *argv, VALUE klass)
{
VALUE name, rest;
long i;
VALUE st;
st_table *tbl;
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS
name = argv[0];
if (SYMBOL_P(name)) {
name = Qnil;
}
else {
--argc;
++argv;
}
rest = rb_ident_hash_new(
RBASIC_CLEAR_CLASS(rest
tbl = RHASH_TBL(rest
for (i=0; i<argc; i++) {
VALUE mem = rb_to_symbol(argv[i]
if (st_insert(tbl, mem, Qtrue)) {
rb_raise(rb_eArgError, "duplicate member: %"PRIsVALUE, mem
}
}
rest = rb_hash_keys(rest
st_clear(tbl
RBASIC_CLEAR_CLASS(rest
OBJ_FREEZE_RAW(rest
if (NIL_P(name)) {
st = anonymous_struct(klass
}
else {
st = new_struct(name, klass
}
setup_struct(st, rest
if (rb_block_given_p()) {
rb_mod_module_eval(0, 0, st
}
return st;
}
公共实例方法
struct == other→true或false显示源代码
Equality-Returns true
如果other
具有相同的结构子类并具有相同的成员值(根据Object#==)。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joejr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
jane = Customer.new("Jane Doe", "456 Elm, Anytown NC", 12345)
joe == joejr #=> true
joe == jane #=> false
static VALUE
rb_struct_equal(VALUE s, VALUE s2)
{
if (s == s2) return Qtrue;
if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse;
if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
rb_bug("inconsistent struct" /* should never happen */
}
return rb_exec_recursive_paired(recursive_equal, s, s2, s2
}
structmember → object 显示源
structindex → object
属性引用 - 返回给定结构的值member
或给定的成员index
。如果member
不存在则引发NameError,如果index
超出范围则引发IndexError 。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe["name"] #=> "Joe Smith"
joe[:name] #=> "Joe Smith"
joe[0] #=> "Joe Smith"
VALUE
rb_struct_aref(VALUE s, VALUE idx)
{
int i = rb_struct_pos(s, &idx
if (i < 0) invalid_struct_pos(s, idx
return RSTRUCT_GET(s, i
}
structmember = obj → obj 显示源
structindex = obj → obj
属性分配 - 设置给定结构member
或给定成员的值index
。如果member
不存在则引发NameError,如果index
超出范围则引发IndexError 。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe["name"] = "Luke"
joe[:zip] = "90210"
joe.name #=> "Luke"
joe.zip #=> "90210"
VALUE
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
{
int i = rb_struct_pos(s, &idx
if (i < 0) invalid_struct_pos(s, idx
rb_struct_modify(s
RSTRUCT_SET(s, i, val
return val;
}
as_json(*) 显示源
返回一个散列,它将变成一个JSON对象并表示这个对象。
# File ext/json/lib/json/add/struct.rb, line 16
def as_json(*)
klass = self.class.name
klass.to_s.empty? and raise JSON::JSONError, "Only named structs are supported!"
{
JSON.create_id => klass,
'v' => values,
}
end
dig(key, ...) → object 显示源
key
通过dig
在每个步骤调用来抽取由对象序列指定的嵌套值,nil
如果有任何中间步骤则返回nil
。
Foo = Struct.new(:a)
f = Foo.new(Foo.new{b: [1, 2, 3]}))
f.dig(:a, :a, :b, 0) # => 1
f.dig(:b, 0) # => nil
f.dig(:a, :a, :b, :c) # TypeError: no implicit conversion of Symbol into Integer
static VALUE
rb_struct_dig(int argc, VALUE *argv, VALUE self)
{
rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS
self = rb_struct_lookup(self, *argv
if (!--argc) return self;
++argv;
return rb_obj_dig(argc, argv, self, Qnil
}
each {|obj| block } → struct 显示源
each → enumerator
按顺序产生每个结构成员的值。如果没有给出块,则返回枚举器。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each {|x| puts(x) }
生产:
Joe Smith
123 Maple, Anytown NC
12345
static VALUE
rb_struct_each(VALUE s)
{
long i;
RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size
for (i=0; i<RSTRUCT_LEN(s i++) {
rb_yield(RSTRUCT_GET(s, i)
}
return s;
}
each_pair {|sym, obj| block } → struct 显示源
each_pair → enumerator
按顺序产生每个结构成员的名称和值。如果没有给出块,则返回枚举器。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each_pair {|name, value| puts("#{name} => #{value}") }
生产:
name => Joe Smith
address => 123 Maple, Anytown NC
zip => 12345
static VALUE
rb_struct_each_pair(VALUE s)
{
VALUE members;
long i;
RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size
members = rb_struct_members(s
if (rb_block_arity() > 1) {
for (i=0; i<RSTRUCT_LEN(s i++) {
VALUE key = rb_ary_entry(members, i
VALUE value = RSTRUCT_GET(s, i
rb_yield_values(2, key, value
}
}
else {
for (i=0; i<RSTRUCT_LEN(s i++) {
VALUE key = rb_ary_entry(members, i
VALUE value = RSTRUCT_GET(s, i
rb_yield(rb_assoc_new(key, value)
}
}
return s;
}
eql?(other) → true or false 显示源
散列相等 - 如果它们具有相同的结构子类并具有相同的成员值(根据Object#eql?)other
,则struct
引用相同的散列键。
static VALUE
rb_struct_eql(VALUE s, VALUE s2)
{
if (s == s2) return Qtrue;
if (!RB_TYPE_P(s2, T_STRUCT)) return Qfalse;
if (rb_obj_class(s) != rb_obj_class(s2)) return Qfalse;
if (RSTRUCT_LEN(s) != RSTRUCT_LEN(s2)) {
rb_bug("inconsistent struct" /* should never happen */
}
return rb_exec_recursive_paired(recursive_eql, s, s2, s2
}
hash → integer 显示源
根据这个结构的内容返回一个散列值。
static VALUE
rb_struct_hash(VALUE s)
{
long i, len;
st_index_t h;
VALUE n;
const VALUE *ptr;
h = rb_hash_start(rb_hash(rb_obj_class(s))
ptr = RSTRUCT_CONST_PTR(s
len = RSTRUCT_LEN(s
for (i = 0; i < len; i++) {
n = rb_hash(ptr[i]
h = rb_hash_uint(h, NUM2LONG(n)
}
h = rb_hash_end(h
return INT2FIX(h
}
to_s → string 显示源
inspect → string
以字符串形式返回此结构的描述。
static VALUE
rb_struct_inspect(VALUE s)
{
return rb_exec_recursive(inspect_struct, s, 0
}
另外别名为:to_s
length → integer 显示源
返回结构成员的数量。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.length #=> 3
VALUE
rb_struct_size(VALUE s)
{
return LONG2FIX(RSTRUCT_LEN(s)
}
members → array 显示源
以符号数组形式返回结构成员:
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.members #=> [:name, :address, :zip]
static VALUE
rb_struct_members_m(VALUE obj)
{
return rb_struct_s_members_m(rb_obj_class(obj)
}
select {|obj| block } → array 显示源
select → enumerator
将每个成员值从结构体传递到块,并返回一个Array struct
,其中包含给定块返回true值(等于Enumerable#select)的成员值。
Lots = Struct.new(:a, :b, :c, :d, :e, :f)
l = Lots.new(11, 22, 33, 44, 55, 66)
l.select {|v| v.even? } #=> [22, 44, 66]
static VALUE
rb_struct_select(int argc, VALUE *argv, VALUE s)
{
VALUE result;
long i;
rb_check_arity(argc, 0, 0
RETURN_SIZED_ENUMERATOR(s, 0, 0, struct_enum_size
result = rb_ary_new(
for (i = 0; i < RSTRUCT_LEN(s i++) {
if (RTEST(rb_yield(RSTRUCT_GET(s, i)))) {
rb_ary_push(result, RSTRUCT_GET(s, i)
}
}
return result;
}
size → integer 显示源
返回结构成员的数量。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.length #=> 3
VALUE
rb_struct_size(VALUE s)
{
return LONG2FIX(RSTRUCT_LEN(s)
}
to_a → array 显示源
以数组形式返回此结构的值。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_a[1] #=> "123 Maple, Anytown NC"
static VALUE
rb_struct_to_a(VALUE s)
{
return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s)
}
to_h → hash 显示源
返回包含结构成员的名称和值的哈希。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_h[:address] #=> "123 Maple, Anytown NC"
static VALUE
rb_struct_to_h(VALUE s)
{
VALUE h = rb_hash_new(
VALUE members = rb_struct_members(s
long i;
for (i=0; i<RSTRUCT_LEN(s i++) {
rb_hash_aset(h, rb_ary_entry(members, i), RSTRUCT_GET(s, i)
}
return h;
}
to_json(*args) 显示源
将具有结构值的类名称(Struct)存储v
为JSON字符串。仅支持命名的结构。
# File ext/json/lib/json/add/struct.rb, line 27
def to_json(*args)
as_json.to_json(*args)
end
to_s()
别名为:检查
values → array 显示源
以数组形式返回此结构的值。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_a[1] #=> "123 Maple, Anytown NC"
static VALUE
rb_struct_to_a(VALUE s)
{
return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s)
}
values_at(selector, ...) → array 显示源
将每个结构成员值selector
作为数组返回。A selector
可以是整数偏移量或偏移量范围(如在Array#values_at中)。
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.values_at(0, 2) #=> ["Joe Smith", 12345]
static VALUE
rb_struct_values_at(int argc, VALUE *argv, VALUE s)
{
return rb_get_values_at(s, RSTRUCT_LEN(s), argc, argv, struct_entry
}