Method: Struct.new
- Defined in:
- struct.c
.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
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. # => nil
f. = 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
: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>
641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 |
# File 'struct.c', line 641
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(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;
}
|