# 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.

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`.

### Constants

Group

  `Group`

  `Group` is a `Struct` that is only available when compiled with `HAVE_GETGRENT`.

  The struct contains the following members:

  name

    contains the name of the group as a `String`.

  passwd

    contains the encrypted password as a `String`. An ‘x’ is returned if password access to the group is not available; an empty string is returned if no password is needed to obtain membership of the group.

    Must be compiled with `HAVE_STRUCT_GROUP_GR_PASSWD`.

  gid

    contains the group’s numeric ID as an integer.

  mem

    is an `Array` of Strings containing the short login names of the members of the group.

Passwd

  `Passwd`

  `Passwd` is a `Struct` that contains the following members:

  name

    contains the short login name of the user as a `String`.

  passwd

    contains the encrypted password of the user as a `String`. an ‘x’ is returned if shadow passwords are in use. An ‘*’ is returned if the user cannot log in using a password.

  uid

    contains the integer user ID (uid) of the user.

  gid

    contains the integer group ID (gid) of the user’s primary group.

  dir

    contains the path to the home directory of the user as a `String`.

  shell

    contains the path to the login shell of the user as a `String`.

  ### The following members below are optional, and must be compiled with special flags:¶ ↑

  gecos

    contains a longer `String` description of the user, such as a full name. Some Unix systems provide structured information in the gecos field, but this is system-dependent. must be compiled with `HAVE_STRUCT_PASSWD_PW_GECOS`

  change

    password change time(integer) must be compiled with `HAVE_STRUCT_PASSWD_PW_CHANGE`

  quota

    quota value(integer) must be compiled with `HAVE_STRUCT_PASSWD_PW_QUOTA`

  age

    password age(integer) must be compiled with `HAVE_STRUCT_PASSWD_PW_AGE`

  class

    user access class(string) must be compiled with `HAVE_STRUCT_PASSWD_PW_CLASS`

  comment

    comment(string) must be compiled with `HAVE_STRUCT_PASSWD_PW_COMMENT`

  expire

    account expiration time(integer) must be compiled with `HAVE_STRUCT_PASSWD_PW_EXPIRE`

### 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 (the default) or via keyword arguments (if `keyword_init: true` is given).

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

  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 are ordinary arguments (not keyword arguments). With optional keyword argument `keyword_init: true`, the new subclass is initialized with keyword arguments:

    # Without keyword_init: true.
    Foo = Struct.new('Foo', :foo, :bar)
    Foo                     # => Struct::Foo
    Foo.new(0, 1)           # => #<struct Struct::Foo foo=0, bar=1>
    # With keyword_init: true.
    Bar = Struct.new(:foo, :bar, keyword_init: true)
    Bar # =>                # => Bar(keyword_init: true)
    Bar.new(bar: 1, foo: 0) # => #<struct Bar foo=0, bar=1>

    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;

        rb_check_arity(argc, 1, UNLIMITED_ARGUMENTS);
        name = argv[0];
        if (SYMBOL_P(name)) {
            name = Qnil;
        }
        else {
            --argc;
            ++argv;
        }

        if (RB_TYPE_P(argv[argc-1], T_HASH)) {
            static ID keyword_ids[1];

            if (!keyword_ids[0]) {
                keyword_ids[0] = rb_intern("keyword_init");
            }
            rb_get_kwargs(argv[argc-1], keyword_ids, 0, 1, &keyword_init);
            if (keyword_init == Qundef) {
                keyword_init = Qnil;
            }
            else if (RTEST(keyword_init)) {
                keyword_init = Qtrue;
            }
            --argc;
        }

        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:

    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:

    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 = ‘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, 0);
    }

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.

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.

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