結構類別

結構類別提供一個便利的方式來建立一個簡單的類別,可以儲存和擷取值。

此範例建立結構的子類別,結構::客戶;第一個引數,字串,是子類別的名稱;其他引數,符號,決定新子類別的「成員」。

Customer = Struct.new('Customer', :name, :address, :zip)
Customer.name       # => "Struct::Customer"
Customer.class      # => Class
Customer.superclass # => Struct

對應到每個成員有兩個方法,一個寫入器和一個讀取器,用來儲存和擷取值

methods = Customer.instance_methods false
methods # => [:zip, :address=, :zip=, :address, :name, :name=]

子類別的執行個體可以透過方法::new建立,並指定其成員的值

joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe # => #<struct Struct::Customer name="Joe Smith", address="123 Maple, Anytown NC", zip=12345>

成員值可以這樣管理

joe.name    # => "Joe Smith"
joe.name = 'Joseph Smith'
joe.name    # => "Joseph Smith"

這樣;請注意,成員名稱可以表示為字串或符號

joe[:name]  # => "Joseph Smith"
joe[:name] = 'Joseph Smith, Jr.'
joe['name'] # => "Joseph Smith, Jr."

請參閱結構::new

此處內容

首先,其他地方是什麼。結構類別

另請參閱資料,這是一個有點類似但更嚴格的概念,用於定義不可變值物件。

在這裡,結構類別提供對下列項目有用的方法

建立結構子類別的方法

  • ::new:傳回結構的新子類別。

查詢方法

  • hash:傳回整數雜湊碼。

  • lengthsize:傳回成員數目。

比較方法

  • ==:傳回給定的物件是否等於 self,使用 == 來比較成員值。

  • eql?:傳回給定的物件是否等於 self,使用 eql? 來比較成員值。

擷取方法

  • []:傳回與給定成員名稱關聯的值。

  • to_avaluesdeconstruct:傳回 self 中的成員值作為陣列。

  • deconstruct_keys:傳回給定成員名稱的名稱/值配對雜湊。

  • dig:傳回巢狀物件中由給定成員名稱和額外引數指定的物件。

  • members:傳回成員名稱的陣列。

  • selectfilter:傳回 self 中的成員值陣列,由給定的區塊選取。

  • values_at:傳回包含給定成員名稱值的陣列。

指定方法

  • []=:將給定值指定給給定成員名稱。

反覆方法

  • each:呼叫每個成員名稱的給定區塊。

  • each_pair:呼叫每個成員名稱/值配對的給定區塊。

轉換方法

  • inspectto_s:傳回 self 的字串表示形式。

  • to_h:傳回 self 中的成員名稱/值配對雜湊。

公開類別方法

StructClass::keyword_init? → true 或假值 按一下以切換來源

如果類別使用 keyword_init: true 初始化,則傳回 true。否則傳回 nilfalse

範例

Foo = Struct.new(:a)
Foo.keyword_init? # => nil
Bar = Struct.new(:a, keyword_init: true)
Bar.keyword_init? # => true
Baz = Struct.new(:a, keyword_init: false)
Baz.keyword_init? # => false
static VALUE
rb_struct_s_keyword_init_p(VALUE obj)
{
}
StructClass::members → 符號陣列 按一下以切換來源

傳回 Struct 後代的成員名稱作為陣列

Customer = Struct.new(:name, :address, :zip)
Customer.members # => [:name, :address, :zip]
static VALUE
rb_struct_s_members_m(VALUE klass)
{
    VALUE members = rb_struct_s_members(klass);

    return rb_ary_dup(members);
}
new(*member_names, keyword_init: nil){|Struct_subclass| ... } → Struct_subclass 按一下以切換來源
new(class_name, *member_names, keyword_init: nil){|Struct_subclass| ... } → Struct_subclass
new(*member_names) → Struct_subclass_instance
new(**member_names) → Struct_subclass_instance

Struct.new 會傳回 Struct 的新子類別。新子類別

  • 可能是匿名的,或具有 class_name 所提供的名稱。

  • 可能具有 member_names 所提供的成員。

  • 可能透過一般引數或關鍵字引數進行初始化

新子類別有自己的方法 ::new;因此

Foo = Struct.new('Foo', :foo, :bar) # => Struct::Foo
f = Foo.new(0, 1)                   # => #<struct Struct::Foo foo=0, bar=1>

類別名稱

若有字串引數 class_name,會傳回名為 Struct::class_nameStruct 新子類別

Foo = Struct.new('Foo', :foo, :bar) # => Struct::Foo
Foo.name                            # => "Struct::Foo"
Foo.superclass                      # => Struct

若沒有字串引數 class_name,會傳回 Struct 的新匿名子類別

Struct.new(:foo, :bar).name # => nil

區塊

若有提供區塊,建立的子類別會傳遞給區塊

Customer = Struct.new('Customer', :name, :address) do |new_class|
  p "The new subclass is #{new_class}"
  def greeting
    "Hello #{name} at #{address}"
  end
end           # => Struct::Customer
dave = Customer.new('Dave', '123 Main')
dave # =>     #<struct Struct::Customer name="Dave", address="123 Main">
dave.greeting # => "Hello Dave at 123 Main"

來自 Struct.new 的輸出

"The new subclass is Struct::Customer"

成員名稱

Symbol 引數 member_names 決定新子類別的成員

Struct.new(:foo, :bar).members        # => [:foo, :bar]
Struct.new('Foo', :foo, :bar).members # => [:foo, :bar]

新子類別有對應於 member_names 的執行個體方法

Foo = Struct.new('Foo', :foo, :bar)
Foo.instance_methods(false) # => [:foo, :bar, :foo=, :bar=]
f = Foo.new                 # => #<struct Struct::Foo foo=nil, bar=nil>
f.foo                       # => nil
f.foo = 0                   # => 0
f.bar                       # => nil
f.bar = 1                   # => 1
f                           # => #<struct Struct::Foo foo=0, bar=1>

單例方法

Struct.new 傳回的子類別有這些單例方法

  • 方法 ::new 會建立子類別的執行個體

    Foo.new          # => #<struct Struct::Foo foo=nil, bar=nil>
    Foo.new(0)       # => #<struct Struct::Foo foo=0, bar=nil>
    Foo.new(0, 1)    # => #<struct Struct::Foo foo=0, bar=1>
    Foo.new(0, 1, 2) # Raises ArgumentError: struct size differs
    
    # Initialization with keyword arguments:
    Foo.new(foo: 0)         # => #<struct Struct::Foo foo=0, bar=nil>
    Foo.new(foo: 0, bar: 1) # => #<struct Struct::Foo foo=0, bar=1>
    Foo.new(foo: 0, bar: 1, baz: 2)
    # Raises ArgumentError: unknown keywords: baz
    
  • 方法 :inspect 會傳回子類別的字串表示形式

    Foo.inspect
    # => "Struct::Foo"
    
  • 方法 ::members 會傳回成員名稱的陣列

    Foo.members # => [:foo, :bar]
    

關鍵字引數

預設情況下,用來初始化新子類別執行個體的引數可以是位置引數和關鍵字引數。

選用的關鍵字引數 keyword_init: 允許強制只接受一種類型的引數

KeywordsOnly = Struct.new(:foo, :bar, keyword_init: true)
KeywordsOnly.new(bar: 1, foo: 0)
# => #<struct KeywordsOnly foo=0, bar=1>
KeywordsOnly.new(0, 1)
# Raises ArgumentError: wrong number of arguments

PositionalOnly = Struct.new(:foo, :bar, keyword_init: false)
PositionalOnly.new(0, 1)
# => #<struct PositionalOnly foo=0, bar=1>
PositionalOnly.new(bar: 1, foo: 0)
# => #<struct PositionalOnly foo={:foo=>1, :bar=>2}, bar=nil>
# Note that no error is raised, but arguments treated as one hash value

# Same as not providing keyword_init:
Any = Struct.new(:foo, :bar, keyword_init: nil)
Any.new(foo: 1, bar: 2)
# => #<struct Any foo=1, bar=2>
Any.new(1, 2)
# => #<struct Any foo=1, bar=2>
static VALUE
rb_struct_s_def(int argc, VALUE *argv, VALUE klass)
{
    VALUE name = Qnil, rest, keyword_init = Qnil;
    long i;
    VALUE st;
    VALUE opt;

    argc = rb_scan_args(argc, argv, "0*:", NULL, &opt);
    if (argc >= 1 && !SYMBOL_P(argv[0])) {
        name = argv[0];
        --argc;
        ++argv;
    }

    if (!NIL_P(opt)) {
        static ID keyword_ids[1];

        if (!keyword_ids[0]) {
            keyword_ids[0] = rb_intern("keyword_init");
        }
        rb_get_kwargs(opt, keyword_ids, 0, 1, &keyword_init);
        if (UNDEF_P(keyword_init)) {
            keyword_init = Qnil;
        }
        else if (RTEST(keyword_init)) {
            keyword_init = Qtrue;
        }
    }

    rest = rb_ident_hash_new();
    RBASIC_CLEAR_CLASS(rest);
    for (i=0; i<argc; i++) {
        VALUE mem = rb_to_symbol(argv[i]);
        if (rb_is_attrset_sym(mem)) {
            rb_raise(rb_eArgError, "invalid struct member: %"PRIsVALUE, mem);
        }
        if (RTEST(rb_hash_has_key(rest, mem))) {
            rb_raise(rb_eArgError, "duplicate member: %"PRIsVALUE, mem);
        }
        rb_hash_aset(rest, mem, Qtrue);
    }
    rest = rb_hash_keys(rest);
    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);
    rb_ivar_set(st, id_keyword_init, keyword_init);
    if (rb_block_given_p()) {
        rb_mod_module_eval(0, 0, st);
    }

    return st;
}

公開執行個體方法

self == other → true or false 按一下以切換來源

僅在下列情況傳回 true;否則傳回 false

  • other.class == self.class.

  • 對於每個成員名稱 nameother.name == self.name

範例

Customer = Struct.new(:name, :address, :zip)
joe    = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe_jr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe_jr == joe # => true
joe_jr[:name] = 'Joe Smith, Jr.'
# => "Joe Smith, Jr."
joe_jr == joe # => 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);
}
struct[name] → object 按一下以切換來源
struct[n] → object

傳回來自 self 的值。

若有提供符號或字串引數 name,會傳回命名成員的值

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe[:zip] # => 12345

如果 name 不是成員名稱,會引發 NameError

若有提供整數引數 n,如果 n 在範圍內,會傳回 self.values[n];請參閱 Array 中的陣列索引

joe[2]  # => 12345
joe[-2] # => "123 Maple, Anytown NC"

如果 n 超出範圍,會引發 IndexError

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);
}
struct[name] = value → value 按一下以切換來源
struct[n] = value → value

將值指定給成員。

如果給定符號或字串引數 name,將給定的 value 指定給命名成員;傳回 value

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe[:zip] = 54321 # => 54321
joe # => #<struct Customer name="Joe Smith", address="123 Maple, Anytown NC", zip=54321>

如果 name 不是成員名稱,會引發 NameError

如果給定整數引數 n,如果 n 在範圍內,將給定的 value 指定給第 n 個成員;請參閱 Array 中的陣列索引

joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe[2] = 54321           # => 54321
joe[-3] = 'Joseph Smith' # => "Joseph Smith"
joe # => #<struct Customer name="Joseph Smith", address="123 Maple, Anytown NC", zip=54321>

如果 n 超出範圍,會引發 IndexError

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;
}
deconstruct()

以陣列形式傳回 self 中的值

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_a # => ["Joe Smith", "123 Maple, Anytown NC", 12345]

相關:members

別名:to_a
deconstruct_keys(array_of_names) → hash 按一下切換來源

傳回給定成員名稱的名稱/值配對的雜湊。

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
h = joe.deconstruct_keys([:zip, :address])
h # => {:zip=>12345, :address=>"123 Maple, Anytown NC"}

如果 array_of_namesnil,傳回所有名稱和值

h = joe.deconstruct_keys(nil)
h # => {:name=>"Joseph Smith, Jr.", :address=>"123 Maple, Anytown NC", :zip=>12345}
static VALUE
rb_struct_deconstruct_keys(VALUE s, VALUE keys)
{
    VALUE h;
    long i;

    if (NIL_P(keys)) {
        return rb_struct_to_h(s);
    }
    if (UNLIKELY(!RB_TYPE_P(keys, T_ARRAY))) {
        rb_raise(rb_eTypeError,
                 "wrong argument type %"PRIsVALUE" (expected Array or nil)",
                 rb_obj_class(keys));

    }
    if (RSTRUCT_LEN(s) < RARRAY_LEN(keys)) {
        return rb_hash_new_with_size(0);
    }
    h = rb_hash_new_with_size(RARRAY_LEN(keys));
    for (i=0; i<RARRAY_LEN(keys); i++) {
        VALUE key = RARRAY_AREF(keys, i);
        int i = rb_struct_pos(s, &key);
        if (i < 0) {
            return h;
        }
        rb_hash_aset(h, key, RSTRUCT_GET(s, i));
    }
    return h;
}
dig(name, *identifiers) → object 按一下切換來源
dig(n, *identifiers) → object

在巢狀物件中尋找並傳回物件。巢狀物件可能是各種類別的執行個體。請參閱 Dig 方法

如果給定符號或字串引數 name,傳回由 nameidentifiers 指定的物件

Foo = Struct.new(:a)
f = Foo.new(Foo.new({b: [1, 2, 3]}))
f.dig(:a) # => #<struct Foo a={:b=>[1, 2, 3]}>
f.dig(:a, :a) # => {:b=>[1, 2, 3]}
f.dig(:a, :a, :b) # => [1, 2, 3]
f.dig(:a, :a, :b, 0) # => 1
f.dig(:b, 0) # => nil

如果給定整數引數 n,傳回由 nidentifiers 指定的物件

f.dig(0) # => #<struct Foo a={:b=>[1, 2, 3]}>
f.dig(0, 0) # => {:b=>[1, 2, 3]}
f.dig(0, 0, :b) # => [1, 2, 3]
f.dig(0, 0, :b, 0) # => 1
f.dig(:b, 0) # => nil
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 {|value| ... } → self 按一下切換來源
each → enumerator

呼叫給定的區塊,並傳入每個成員的值;傳回 self

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each {|value| p value }

輸出

"Joe Smith"
"123 Maple, Anytown NC"
12345

如果未給定區塊,傳回 Enumerator

相關:each_pair

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 {|(name, value)| ... } → self 按一下切換來源
each_pair → enumerator

呼叫給定的區塊,並傳入每個成員名稱/值配對;傳回 self

Customer = Struct.new(:name, :address, :zip) # => Customer
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each_pair {|(name, value)| p "#{name} => #{value}" }

輸出

"name => Joe Smith"
"address => 123 Maple, Anytown NC"
"zip => 12345"

如果未給定區塊,傳回 Enumerator

相關:each

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_pair_yield_optimizable()) {
        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 按一下切換來源

僅在下列情況傳回 true;否則傳回 false

  • other.class == self.class.

  • 對於每個成員名稱 nameother.name.eql?(self.name)

    Customer = Struct.new(:name, :address, :zip)
    joe    = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
    joe_jr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
    joe_jr.eql?(joe) # => true
    joe_jr[:name] = 'Joe Smith, Jr.'
    joe_jr.eql?(joe) # => false
    

相關:Object#==

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);
}
filter(*args)

如果給定區塊,傳回 self 中區塊傳回真值的值的陣列

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
a = joe.select {|value| value.is_a?(String) }
a # => ["Joe Smith", "123 Maple, Anytown NC"]
a = joe.select {|value| value.is_a?(Integer) }
a # => [12345]

如果未給定區塊,傳回 Enumerator

別名:select
hash → integer 按一下切換來源

傳回 self 的整數雜湊值。

同一個類別且內容相同的兩個結構將具有相同的雜湊碼(並且會使用 Struct#eql? 進行比較)

Customer = Struct.new(:name, :address, :zip)
joe    = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe_jr = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.hash == joe_jr.hash # => true
joe_jr[:name] = 'Joe Smith, Jr.'
joe.hash == joe_jr.hash # => false

相關:Object#hash

static VALUE
rb_struct_hash(VALUE s)
{
    long i, len;
    st_index_t h;
    VALUE n;

    h = rb_hash_start(rb_hash(rb_obj_class(s)));
    len = RSTRUCT_LEN(s);
    for (i = 0; i < len; i++) {
        n = rb_hash(RSTRUCT_GET(s, i));
        h = rb_hash_uint(h, NUM2LONG(n));
    }
    h = rb_hash_end(h);
    return ST2FIX(h);
}
inspect → 字串 按一下以切換來源

傳回 self 的字串表示。

Customer = Struct.new(:name, :address, :zip) # => Customer
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.inspect # => "#<struct Customer name=\"Joe Smith\", address=\"123 Maple, Anytown NC\", zip=12345>"
static VALUE
rb_struct_inspect(VALUE s)
{
    return rb_exec_recursive(inspect_struct, s, rb_str_new2("#<struct "));
}
別名為:to_s
length()

傳回成員數目。

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.size #=> 3
別名為:size
members → 符號陣列 按一下以切換來源

傳回 self 的成員名稱,以陣列表示。

Customer = Struct.new(:name, :address, :zip)
Customer.new.members # => [:name, :address, :zip]

相關:to_a

static VALUE
rb_struct_members_m(VALUE obj)
{
    return rb_struct_s_members_m(rb_obj_class(obj));
}
select {|value| ... } → 陣列 按一下以切換來源
select → 列舉器

如果給定區塊,傳回 self 中區塊傳回真值的值的陣列

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
a = joe.select {|value| value.is_a?(String) }
a # => ["Joe Smith", "123 Maple, Anytown NC"]
a = joe.select {|value| value.is_a?(Integer) }
a # => [12345]

如果未給定區塊,傳回 Enumerator

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;
}
別名為:filter
size → 整數 按一下以切換來源

傳回成員數目。

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.size #=> 3
VALUE
rb_struct_size(VALUE s)
{
    return LONG2FIX(RSTRUCT_LEN(s));
}
別名為:length
to_a → 陣列 按一下以切換來源

以陣列形式傳回 self 中的值

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_a # => ["Joe Smith", "123 Maple, Anytown NC", 12345]

相關:members

static VALUE
rb_struct_to_a(VALUE s)
{
    return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s));
}
別名為:valuesdeconstruct
to_h → hash 按一下以切換來源
to_h {|name, value| ... } → hash

傳回包含每個成員名稱和值的 hash。

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
h = joe.to_h
h # => {:name=>"Joe Smith", :address=>"123 Maple, Anytown NC", :zip=>12345}

如果給定區塊,則會使用每個名稱/值對呼叫該區塊;區塊應傳回一個 2 元素陣列,其元素將成為傳回 hash 中的鍵/值對

h = joe.to_h{|name, value| [name.upcase, value.to_s.upcase]}
h # => {:NAME=>"JOE SMITH", :ADDRESS=>"123 MAPLE, ANYTOWN NC", :ZIP=>"12345"}

如果區塊傳回不適當的值,則會引發 ArgumentError

static VALUE
rb_struct_to_h(VALUE s)
{
    VALUE h = rb_hash_new_with_size(RSTRUCT_LEN(s));
    VALUE members = rb_struct_members(s);
    long i;
    int block_given = rb_block_given_p();

    for (i=0; i<RSTRUCT_LEN(s); i++) {
        VALUE k = rb_ary_entry(members, i), v = RSTRUCT_GET(s, i);
        if (block_given)
            rb_hash_set_pair(h, rb_yield_values(2, k, v));
        else
            rb_hash_aset(h, k, v);
    }
    return h;
}
to_s()

傳回 self 的字串表示。

Customer = Struct.new(:name, :address, :zip) # => Customer
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.inspect # => "#<struct Customer name=\"Joe Smith\", address=\"123 Maple, Anytown NC\", zip=12345>"
別名為:inspect
values()

以陣列形式傳回 self 中的值

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_a # => ["Joe Smith", "123 Maple, Anytown NC", 12345]

相關:members

別名:to_a
values_at(*integers) → 陣列 按一下以切換來源
values_at(integer_range) → 陣列

傳回 self 的值陣列。

給定整數引數 integers 時,傳回包含 integers 中一個所提供每個值的陣列

Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.values_at(0, 2)    # => ["Joe Smith", 12345]
joe.values_at(2, 0)    # => [12345, "Joe Smith"]
joe.values_at(2, 1, 0) # => [12345, "123 Maple, Anytown NC", "Joe Smith"]
joe.values_at(0, -3)   # => ["Joe Smith", "Joe Smith"]

如果任何 integers 超出範圍,則會引發 IndexError;請參閱 Array 中的 Array Indexes

給定整數範圍引數 integer_range 時,傳回包含範圍元素所提供每個值的陣列;對於大於結構的範圍元素,會填入 nil

joe.values_at(0..2)
# => ["Joe Smith", "123 Maple, Anytown NC", 12345]
joe.values_at(-3..-1)
# => ["Joe Smith", "123 Maple, Anytown NC", 12345]
joe.values_at(1..4) # => ["123 Maple, Anytown NC", 12345, nil, nil]

如果範圍的任何元素為負數且超出範圍,則會引發 RangeError;請參閱 Array 中的 Array Indexes

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);
}