class Struct::Value

Struct::Value is a simplified version of Struct, representing immutable and non-Enumerable value object, useful for producing code in functional style. Value's definition is performed the same way as Struct's, but, unlike Struct, Value lacks the following features:

The latter is because objects with to_a methods could be unpacked unexpectedly, which is usually inconvenient for value objects.

S = Struct.new(:a, :b)
V = Struct::Value.new(:a, :b)

def test(*args)
  p ["Args:", args]
end

test(*S.new(1, 2)) # => ["Args:", [1, 2]]
test(*V.new(1, 2)) # => ["Args:", [#<value V a=1, b=2>]]

The rest of Value's limitations targets making the class' goal and usage more focused: it is just _a value_, not a collection, and not a temporary storage for related yet changing data.

Public Class Methods

Struct::Value.new([class_name] [, member_name]+) → ValueClass click to toggle source
Struct::Value.new([class_name] [, member_name]+, keyword_init: true) → ValueClass
Struct::Value.new([class_name] [, member_name]+) {|ValueClass| block } → ValueClass
new(value, ...) → object
ValueClass[value, ...] → object

The first two forms are used to create a new Struct::Value subclass class_name that can contain a value for each member_name. This subclass can be used to create instances of the value like any other Class.

See Struct.new for details of defining subclasses, the logic is exactly the same for Value.

static VALUE
rb_struct_value_s_def(int argc, VALUE *argv, VALUE klass)
{
    VALUE rest, keyword_init;
    VALUE name = Qnil;
    long i;
    VALUE st;
    st_table *tbl;

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

    if (RB_TYPE_P(argv[argc-1], T_HASH)) {
        VALUE kwargs[1];
        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, kwargs);
        --argc;
        keyword_init = kwargs[0];
    }
    else {
        keyword_init = Qfalse;
    }

    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, true);
    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

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

Equality—Returns true if other has the same value subclass and has equal member values (according to Object#==).

Customer = Struct::Value.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_value_equal(VALUE s, VALUE s2)
{
}
deconstruct → array click to toggle source

Returns the values for usage in a pattern matching:

Customer = Struct::Value.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
case joe
in "Joe Smith", *rest
  ....
static VALUE
rb_struct_value_deconstruct(VALUE s)
{
}
each_pair {|sym, obj| block } → value click to toggle source
each_pair → enumerator

Yields the name and value of each struct member in order. If no block is given an enumerator is returned.

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

Produces:

name => Joe Smith
address => 123 Maple, Anytown NC
zip => 12345
static VALUE
rb_struct_value_each_pair(VALUE s)
{
}
eql?(other) → true or false click to toggle source

Hash equality—other and struct refer to the same hash key if they have the same value subclass and have equal member values (according to Object#eql?).

static VALUE
rb_struct_value_eql(VALUE s, VALUE s2)
{
}
hash → integer click to toggle source

Returns a hash value based on this value's contents.

See also Object#hash.

static VALUE
rb_struct_value_hash(VALUE s)
{
}
to_s → string click to toggle source
inspect → string

Returns a description of this value as a string.

static VALUE
rb_struct_value_inspect(VALUE s)
{
}
Also aliased as: to_s, to_s
members → array click to toggle source

Returns the value members as an array of symbols:

Customer = Struct::Value.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.members   #=> [:name, :address, :zip]
static VALUE
rb_struct_value_members_m(VALUE obj)
{
}
to_h → hash click to toggle source
to_h {|name, value| block } → hash

Returns a Hash containing the names and values for the Value's members.

If a block is given, the results of the block on each pair of the receiver will be used as pairs.

Customer = Struct::Value.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.to_h[:address]   #=> "123 Maple, Anytown NC"
joe.to_h{|name, value| [name.upcase, value.to_s.upcase]}[:ADDRESS]
                     #=> "123 MAPLE, ANYTOWN NC"
static VALUE
rb_struct_value_to_h(VALUE s)
{
}
to_s()
Alias for: inspect