# class Struct

Class Struct provides a convenient way to create a simple class that can store and fetch values.

This example creates a subclass of `Struct`, `Struct::Customer`; the first argument, a string, is the name of the subclass; the other arguments, symbols, determine the members of the new subclass.

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

Corresponding to each member are two methods, a writer and a reader, that store and fetch values:

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

An instance of the subclass may be created, and its members assigned values, via method `::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>

The member values may be managed thus:

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

And thus; note that member name may be expressed as either a string or a symbol:

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

See `Struct::new`.

## What’s Here¶ ↑

First, what’s elsewhere. Class Struct:

- Inherits from class Object.

- Includes module Enumerable, which provides dozens of additional methods.

See also `Data`, which is a somewhat similar, but stricter concept for defining immutable value objects.

Here, class Struct provides methods that are useful for:

- Creating a Struct Subclass

- Querying

- Comparing

- Fetching

- Assigning

- Iterating

- Converting

### Methods for Creating a `Struct` Subclass¶ ↑

- `::new`: Returns a new subclass of Struct.

### Methods for Querying¶ ↑

- `hash`: Returns the integer hash code.

- `length`, `size`: Returns the number of members.

### Methods for Comparing¶ ↑

- `==`: Returns whether a given object is equal to `self`, using `==` to compare member values.

- `eql?`: Returns whether a given object is equal to `self`, using `eql?` to compare member values.

### Methods for Fetching¶ ↑

- `[]`: Returns the value associated with a given member name.

- `to_a`, `values`, `deconstruct`: Returns the member values in `self` as an array.

- `deconstruct_keys`: Returns a hash of the name/value pairs for given member names.

- `dig`: Returns the object in nested objects that is specified by a given member name and additional arguments.

- `members`: Returns an array of the member names.

- `select`, `filter`: Returns an array of member values from `self`, as selected by the given block.

- `values_at`: Returns an array containing values for given member names.

### Methods for Assigning¶ ↑

- `[]=`: Assigns a given value to a given member name.

### Methods for Iterating¶ ↑

- `each`: Calls a given block with each member name.

- `each_pair`: Calls a given block with each member name/value pair.

### Methods for Converting¶ ↑

- `inspect`, `to_s`: Returns a string representation of `self`.

- `to_h`: Returns a hash of the member name/value pairs in `self`.

### Public Class Methods

json_create(object) click to toggle source

Deserializes `JSON` string by constructing new `Struct` object with values `v` serialized by `to_json`.

    # File ext/json/lib/json/add/struct.rb, line 10
    def self.json_create(object)
      new(*object['v'])
    end

StructClass::keyword_init? → true or falsy value click to toggle source

Returns `true` if the class was initialized with `keyword_init: true`. Otherwise returns `nil` or `false`.

Examples:

    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 → array_of_symbols click to toggle source

Returns the member names of the `Struct` descendant as an array:

    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: false){|Struct_subclass| ... } → Struct_subclass click to toggle source
new(class_name, *member_names, keyword_init: false){|Struct_subclass| ... } → Struct_subclass
new(*member_names) → Struct_subclass_instance
new(**member_names) → Struct_subclass_instance

`Struct.new` returns a new subclass of `Struct`. The new subclass:

- May be anonymous, or may have the name given by `class_name`.

- May have members as given by `member_names`.

- May have initialization via ordinary arguments, or via keyword arguments

The new subclass has its own method `::new`; thus:

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

Class Name

With string argument `class_name`, returns a new subclass of `Struct` named `Struct::class_name`:

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

Without string argument `class_name`, returns a new anonymous subclass of `Struct`:

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

Block

With a block given, the created subclass is yielded to the block:

    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"

Output, from `Struct.new`:

    "The new subclass is Struct::Customer"

Member Names

Symbol arguments `member_names` determines the members of the new subclass:

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

The new subclass has instance methods corresponding to `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>

Singleton Methods

A subclass returned by `Struct.new` has these singleton methods:

- Method `::new` creates an instance of the subclass:

      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

  Method `::[]` is an alias for method `::new`.

- Method `:inspect` returns a string representation of the subclass:

      Foo.inspect
      # => "Struct::Foo"

- Method `::members` returns an array of the member names:

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

Keyword Argument

By default, the arguments for initializing an instance of the new subclass can be both positional and keyword arguments.

Optional keyword argument `keyword_init:` allows to force only one type of arguments to be accepted:

    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, rest, keyword_init = Qnil;
        long i;
        VALUE st;
        st_table *tbl;
        VALUE opt;

        argc = rb_scan_args(argc, argv, "1*:", NULL, NULL, &opt);
        name = argv[0];
        if (SYMBOL_P(name)) {
            name = Qnil;
        }
        else {
            --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);
        OBJ_WB_UNPROTECT(rest);
        tbl = RHASH_TBL_RAW(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 (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);
        rb_ivar_set(st, id_keyword_init, keyword_init);
        if (rb_block_given_p()) {
            rb_mod_module_eval(0, 0, st);
        }

        return st;
    }

### Public Instance Methods

self == other → true or false click to toggle source

Returns `true` if and only if the following are true; otherwise returns `false`:

- `other.class == self.class`.

- For each member name `name`, `other.name == self.name`.

Examples:

    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 click to toggle source
struct[n] → object

Returns a value from `self`.

With symbol or string argument `name` given, returns the value for the named member:

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

Raises `NameError` if `name` is not the name of a member.

With integer argument `n` given, returns `self.values[n]` if `n` is in range; see Array Indexes at `Array`:

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

Raises `IndexError` if `n` is out of range.

    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 click to toggle source
struct[n] = value → value

Assigns a value to a member.

With symbol or string argument `name` given, assigns the given `value` to the named member; returns `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>

Raises `NameError` if `name` is not the name of a member.

With integer argument `n` given, assigns the given `value` to the `n`-th member if `n` is in range; see Array Indexes at `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>

Raises `IndexError` if `n` is out of range.

    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(*) click to toggle source

Returns a hash, that will be turned into a `JSON` object and represent this object.

    # 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

deconstruct()

Returns the values in `self` as an array:

    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]

`Struct#values` and `Struct#deconstruct` are aliases for `Struct#to_a`.

Related: `members`.

Alias for: to_a
deconstruct_keys(array_of_names) → hash click to toggle source

Returns a hash of the name/value pairs for the given member names.

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

Returns all names and values if `array_of_names` is `nil`:

    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 click to toggle source
dig(n, *identifiers) → object

Finds and returns an object among nested objects. The nested objects may be instances of various classes. See Dig Methods.

Given symbol or string argument `name`, returns the object that is specified by `name` and `identifiers`:

    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

Given integer argument `n`, returns the object that is specified by `n` and `identifiers`:

    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 click to toggle source
each → enumerator

Calls the given block with the value of each member; returns `self`:

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

Output:

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

Returns an `Enumerator` if no block is given.

Related: `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 click to toggle source
each_pair → enumerator

Calls the given block with each member name/value pair; returns `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}" }

Output:

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

Returns an `Enumerator` if no block is given.

Related: `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 click to toggle source

Returns `true` if and only if the following are true; otherwise returns `false`:

- `other.class == self.class`.

- For each member name `name`, `other.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

Related: `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)

With a block given, returns an array of values from `self` for which the block returns a truthy value:

    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]

With no block given, returns an `Enumerator`.

`Struct#filter` is an alias for `Struct#select`.

Alias for: select
hash → integer click to toggle source

Returns the integer hash value for `self`.

Two structs of the same class and with the same content will have the same hash code (and will compare using `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

Related: `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 → string click to toggle source

Returns a string representation of `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>"

`Struct#to_s` is an alias for `Struct#inspect`.

    static VALUE
    rb_struct_inspect(VALUE s)
    {
        return rb_exec_recursive(inspect_struct, s, rb_str_new2("#<struct "));
    }

Also aliased as: to_s
length()

Returns the number of members.

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

`Struct#length` is an alias for `Struct#size`.

Alias for: size
members → array_of_symbols click to toggle source

Returns the member names from `self` as an array:

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

Related: `to_a`.

    static VALUE
    rb_struct_members_m(VALUE obj)
    {
        return rb_struct_s_members_m(rb_obj_class(obj));
    }

select {|value| ... } → array click to toggle source
select → enumerator

With a block given, returns an array of values from `self` for which the block returns a truthy value:

    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]

With no block given, returns an `Enumerator`.

`Struct#filter` is an alias for `Struct#select`.

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

Also aliased as: filter
size → integer click to toggle source

Returns the number of members.

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

`Struct#length` is an alias for `Struct#size`.

    VALUE
    rb_struct_size(VALUE s)
    {
        return LONG2FIX(RSTRUCT_LEN(s));
    }

Also aliased as: length
to_a → array click to toggle source

Returns the values in `self` as an array:

    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]

`Struct#values` and `Struct#deconstruct` are aliases for `Struct#to_a`.

Related: `members`.

    static VALUE
    rb_struct_to_a(VALUE s)
    {
        return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_CONST_PTR(s));
    }

Also aliased as: values, deconstruct
to_h → hash click to toggle source
to_h {|name, value| ... } → hash

Returns a hash containing the name and value for each member:

    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}

If a block is given, it is called with each name/value pair; the block should return a 2-element array whose elements will become a key/value pair in the returned hash:

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

Raises `ArgumentError` if the block returns an inappropriate value.

    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_json(*args) click to toggle source

Stores class name (`Struct`) with `Struct` values `v` as a `JSON` string. Only named structs are supported.

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

to_s()

Returns a string representation of `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>"

`Struct#to_s` is an alias for `Struct#inspect`.

Alias for: inspect
values()

Returns the values in `self` as an array:

    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]

`Struct#values` and `Struct#deconstruct` are aliases for `Struct#to_a`.

Related: `members`.

Alias for: to_a
values_at(*integers) → array click to toggle source
values_at(integer_range) → array

Returns an array of values from `self`.

With integer arguments `integers` given, returns an array containing each value given by one of `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"]

Raises `IndexError` if any of `integers` is out of range; see Array Indexes at `Array`.

With integer range argument `integer_range` given, returns an array containing each value given by the elements of the range; fills with `nil` values for range elements larger than the structure:

    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]

Raises `RangeError` if any element of the range is negative and out of range; see Array Indexes at `Array`.

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