Class: Struct
Overview
A Struct
is a convenient way to bundle a number of attributes together, using accessor methods, without having to write an explicit class.
The Struct
class is a generator of specific classes, each one of which is defined to hold a set of variables and their accessors. In these examples, we'll call the generated class "CustomerClass," and we'll show an example instance of that class as "CustomerInst."
In the descriptions that follow, the parameter symbol refers to a symbol, which is either a quoted string or a Symbol
(such as :name
).
Class Method Summary collapse
-
.new ⇒ Object
Creates a new class, named by aString, containing accessor methods for the given symbols.
Instance Method Summary collapse
-
#==(other_struct) ⇒ Boolean
Equality---Returns
true
if other_struct is equal to this one: they must be of the same class as generated byStruct::new
, and the values of all instance variables must be equal (according toObject#==
). -
#[] ⇒ Object
Attribute Reference---Returns the value of the instance variable named by symbol, or indexed (0..length-1) by fixnum.
-
#[]= ⇒ Object
Attribute Assignment---Assigns to the instance variable named by symbol or fixnum the value obj and returns it.
-
#each ⇒ Object
Calls block once for each instance variable, passing the value as a parameter.
-
#each_pair ⇒ Object
Calls block once for each instance variable, passing the name (as a symbol) and the value as parameters.
-
#eql?(other) ⇒ Boolean
Two structures are equal if they are the same object, or if all their fields are equal (using
eql?
). -
#hash ⇒ Fixnum
Return a hash value based on this struct's contents.
- #initialize ⇒ Object constructor
-
#initialize_copy ⇒ Object
:nodoc:.
-
#inspect ⇒ Object
(also: #to_s)
Describe the contents of this struct in a string.
-
#length ⇒ Object
Returns the number of instance variables.
-
#members ⇒ Array
Returns an array of symbols representing the names of the instance variables.
-
#select ⇒ Object
Invokes the block passing in successive elements from struct, returning an array containing those elements for which the block returns a true value (equivalent to
Enumerable#select
). -
#size ⇒ Object
Returns the number of instance variables.
-
#to_a ⇒ Object
Returns the values for this instance as an array.
-
#to_h ⇒ Hash
Returns the values for this instance as a hash with keys corresponding to the instance variable name.
-
#values ⇒ Object
Returns the values for this instance as an array.
-
#values_at(selector, ...) ⇒ Array
Returns an array containing the elements in
self
corresponding to the given selector(s).
Methods included from Enumerable
#all?, #any?, #chunk, #collect, #collect_concat, #count, #cycle, #detect, #drop, #drop_while, #each_cons, #each_entry, #each_slice, #each_with_index, #each_with_object, #entries, #find, #find_all, #find_index, #first, #flat_map, #grep, #group_by, #include?, #inject, #lazy, #map, #max, #max_by, #member?, #min, #min_by, #minmax, #minmax_by, #none?, #one?, #partition, #reduce, #reject, #reverse_each, #slice_before, #sort, #sort_by, #take, #take_while, #zip
Constructor Details
#initialize ⇒ Object
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 |
# File 'struct.c', line 368
static VALUE
rb_struct_initialize_m(int argc, VALUE *argv, VALUE self)
{
VALUE klass = rb_obj_class(self);
long n;
rb_struct_modify(self);
n = num_members(klass);
if (n < argc) {
rb_raise(rb_eArgError, "struct size differs");
}
MEMCPY(RSTRUCT_PTR(self), argv, VALUE, argc);
if (n > argc) {
rb_mem_clear(RSTRUCT_PTR(self)+argc, n-argc);
}
return Qnil;
}
|
Class Method Details
.new([aString][, aSym]) ⇒ StructClass .new([aString][, aSym]) {|StructClass| ... } ⇒ StructClass .new(arg, ...) ⇒ Object .[](arg, ...) ⇒ Object
Creates a new class, named by aString, containing accessor methods for the given symbols. If the name aString is omitted, an anonymous structure class will be created. Otherwise, the name of this struct will appear as a constant in class Struct
, so it must be unique for all Struct
s in the system and should start with a capital letter. Assigning a structure class to a constant effectively gives the class the name of the constant.
If a block is given, it will be evaluated in the context of StructClass, passing StructClass as a parameter.
Customer = Struct.new(:name, :address) do
def greeting
"Hello #{name}!"
end
end
Customer.new("Dave", "123 Main").greeting # => "Hello Dave!"
Struct::new
returns a new Class
object, which can then be used to create specific instances of the new structure. The number of actual parameters must be less than or equal to the number of attributes defined for this class; unset parameters default to nil
. Passing too many parameters will raise an ArgumentError
.
The remaining methods listed in this section (class and instance) are defined for this generated class.
# Create a structure with a name in 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">
329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 |
# File 'struct.c', line 329
static VALUE
rb_struct_s_def(int argc, VALUE *argv, VALUE klass)
{
VALUE name, rest;
long i;
VALUE st;
ID id;
rb_scan_args(argc, argv, "1*", &name, &rest);
if (!NIL_P(name) && SYMBOL_P(name)) {
rb_ary_unshift(rest, name);
name = Qnil;
}
for (i=0; i<RARRAY_LEN(rest); i++) {
id = rb_to_id(RARRAY_PTR(rest)[i]);
RARRAY_PTR(rest)[i] = ID2SYM(id);
}
st = make_struct(name, rest, klass);
if (rb_block_given_p()) {
rb_mod_module_eval(0, 0, st);
}
return st;
}
|
Instance Method Details
#==(other_struct) ⇒ Boolean
Equality---Returns true
if other_struct is equal to this one: they must be of the same class as generated by Struct::new
, and the values of all instance variables must be equal (according to 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
854 855 856 857 858 859 860 861 862 863 864 865 |
# File 'struct.c', line 854
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);
}
|
#[](symbol) ⇒ Object #[](fixnum) ⇒ Object
Attribute Reference---Returns the value of the instance variable named by symbol, or indexed (0..length-1) by fixnum. Will raise NameError
if the named variable does not exist, or IndexError
if the index is out of range.
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"
670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 |
# File 'struct.c', line 670
VALUE
rb_struct_aref(VALUE s, VALUE idx)
{
long i;
if (RB_TYPE_P(idx, T_STRING) || RB_TYPE_P(idx, T_SYMBOL)) {
return rb_struct_aref_id(s, rb_to_id(idx));
}
i = NUM2LONG(idx);
if (i < 0) i = RSTRUCT_LEN(s) + i;
if (i < 0)
rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
i, RSTRUCT_LEN(s));
if (RSTRUCT_LEN(s) <= i)
rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
i, RSTRUCT_LEN(s));
return RSTRUCT_PTR(s)[i];
}
|
#[]=(symbol) ⇒ Object #[]=(fixnum) ⇒ Object
Attribute Assignment---Assigns to the instance variable named by symbol or fixnum the value obj and returns it. Will raise a NameError
if the named variable does not exist, or an IndexError
if the index is out of range.
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"
737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 |
# File 'struct.c', line 737
VALUE
rb_struct_aset(VALUE s, VALUE idx, VALUE val)
{
long i;
if (RB_TYPE_P(idx, T_STRING) || RB_TYPE_P(idx, T_SYMBOL)) {
return rb_struct_aset_id(s, rb_to_id(idx), val);
}
i = NUM2LONG(idx);
if (i < 0) i = RSTRUCT_LEN(s) + i;
if (i < 0) {
rb_raise(rb_eIndexError, "offset %ld too small for struct(size:%ld)",
i, RSTRUCT_LEN(s));
}
if (RSTRUCT_LEN(s) <= i) {
rb_raise(rb_eIndexError, "offset %ld too large for struct(size:%ld)",
i, RSTRUCT_LEN(s));
}
rb_struct_modify(s);
return RSTRUCT_PTR(s)[i] = val;
}
|
#each {|obj| ... } ⇒ Object #each ⇒ Object
Calls block once for each instance variable, passing the value as a parameter.
If no block is given, an enumerator is returned instead.
Customer = Struct.new(:name, :address, :zip)
joe = Customer.new("Joe Smith", "123 Maple, Anytown NC", 12345)
joe.each {|x| puts(x) }
produces:
Joe Smith
123 Maple, Anytown NC
12345
465 466 467 468 469 470 471 472 473 474 475 |
# File 'struct.c', line 465
static VALUE
rb_struct_each(VALUE s)
{
long i;
RETURN_SIZED_ENUMERATOR(s, 0, 0, rb_struct_size);
for (i=0; i<RSTRUCT_LEN(s); i++) {
rb_yield(RSTRUCT_PTR(s)[i]);
}
return s;
}
|
#each_pair {|sym, obj| ... } ⇒ Object #each_pair ⇒ Object
Calls block once for each instance variable, passing the name (as a symbol) and the value as parameters.
If no block is given, an enumerator is returned instead.
Customer = Struct.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
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 |
# File 'struct.c', line 498
static VALUE
rb_struct_each_pair(VALUE s)
{
VALUE members;
long i;
RETURN_SIZED_ENUMERATOR(s, 0, 0, rb_struct_size);
members = rb_struct_members(s);
for (i=0; i<RSTRUCT_LEN(s); i++) {
VALUE key = rb_ary_entry(members, i);
VALUE value = RSTRUCT_PTR(s)[i];
rb_yield(rb_assoc_new(key, value));
}
return s;
}
|
#eql?(other) ⇒ Boolean
Two structures are equal if they are the same object, or if all their fields are equal (using eql?
).
924 925 926 927 928 929 930 931 932 933 934 935 |
# File 'struct.c', line 924
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 ⇒ Fixnum
Return a hash value based on this struct's contents.
894 895 896 897 898 |
# File 'struct.c', line 894
static VALUE
rb_struct_hash(VALUE s)
{
return rb_exec_recursive_outer(recursive_hash, s, 0);
}
|
#initialize_copy ⇒ Object
:nodoc:
619 620 621 622 623 624 625 626 627 628 629 |
# File 'struct.c', line 619
VALUE
rb_struct_init_copy(VALUE copy, VALUE s)
{
if (!OBJ_INIT_COPY(copy, s)) return copy;
if (RSTRUCT_LEN(copy) != RSTRUCT_LEN(s)) {
rb_raise(rb_eTypeError, "struct size mismatch");
}
MEMCPY(RSTRUCT_PTR(copy), RSTRUCT_PTR(s), VALUE, RSTRUCT_LEN(copy));
return copy;
}
|
#to_s ⇒ String #inspect ⇒ String Also known as: to_s
Describe the contents of this struct in a string.
569 570 571 572 573 |
# File 'struct.c', line 569
static VALUE
rb_struct_inspect(VALUE s)
{
return rb_exec_recursive(inspect_struct, s, 0);
}
|
#length ⇒ Fixnum #size ⇒ Fixnum
949 950 951 952 953 |
# File 'struct.c', line 949
static VALUE
rb_struct_size(VALUE s)
{
return LONG2FIX(RSTRUCT_LEN(s));
}
|
#members ⇒ Array
84 85 86 87 88 |
# File 'struct.c', line 84
static VALUE
rb_struct_members_m(VALUE obj)
{
return rb_struct_s_members_m(rb_obj_class(obj));
}
|
#select {|i| ... } ⇒ Array #select ⇒ Object
Invokes the block passing in successive elements from struct, returning an array containing those elements for which the block returns a true value (equivalent to Enumerable#select
).
Lots = Struct.new(:a, :b, :c, :d, :e, :f)
l = Lots.new(11, 22, 33, 44, 55, 66)
l.select {|v| (v % 2).zero? } #=> [22, 44, 66]
803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 |
# File 'struct.c', line 803
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, rb_struct_size);
result = rb_ary_new();
for (i = 0; i < RSTRUCT_LEN(s); i++) {
if (RTEST(rb_yield(RSTRUCT_PTR(s)[i]))) {
rb_ary_push(result, RSTRUCT_PTR(s)[i]);
}
}
return result;
}
|
#length ⇒ Fixnum #size ⇒ Fixnum
949 950 951 952 953 |
# File 'struct.c', line 949
static VALUE
rb_struct_size(VALUE s)
{
return LONG2FIX(RSTRUCT_LEN(s));
}
|
#to_a ⇒ Array #values ⇒ Array
587 588 589 590 591 |
# File 'struct.c', line 587
static VALUE
rb_struct_to_a(VALUE s)
{
return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_PTR(s));
}
|
#to_h ⇒ Hash
605 606 607 608 609 610 611 612 613 614 615 616 |
# File 'struct.c', line 605
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_PTR(s)[i]);
}
return h;
}
|
#to_a ⇒ Array #values ⇒ Array
587 588 589 590 591 |
# File 'struct.c', line 587
static VALUE
rb_struct_to_a(VALUE s)
{
return rb_ary_new4(RSTRUCT_LEN(s), RSTRUCT_PTR(s));
}
|
#values_at(selector, ...) ⇒ Array
Returns an array containing the elements in
+self+ corresponding to the given selector(s). The selectors
may be either integer indices or ranges.
See also </code>.select<code>.
a = %w{ a b c d e f }
a.values_at(1, 3, 5)
a.values_at(1, 3, 5, 7)
a.values_at(-1, -3, -5, -7)
a.values_at(1..3, 2...5)
782 783 784 785 786 |
# File 'struct.c', line 782
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);
}
|