Class: Union
- Inherits:
-
Struct
- Object
- Struct
- Union
- Defined in:
- lib/union.rb
Overview
The Union class provides an analogue of a C union. Only one member of a Union object can be set to a non-nil value at a time.
Constant Summary collapse
- VERSION =
The version of the union library
'1.3.0'
Instance Method Summary collapse
-
#[]=(symbol, value) ⇒ Object
Identical to Struct attribute assignment, except that setting one instance variable sets all other instance variables to nil.
-
#current_value ⇒ Object
Returns the current value (the value of the non-nil member) Returns nil if no member is set.
-
#initialize ⇒ Union
constructor
Creates and returns a new Union.
-
#which_member ⇒ Object
Returns the name of the currently set member (the one with a non-nil value) Returns nil if no member is set.
Constructor Details
#initialize ⇒ Union
Creates and returns a new Union. Unlike Struct::Class.new, this does not take any arguments. You must assign attributes individually.
Union.new('Human', :name, :age)
h = Union::Human.new
h.name = 'Daniel' # => #<struct Union::Human name="Daniel", age=nil>
h.age = 38 # => #<struct Union::Human name=nil, age=38>
– The semantics of Union.new(arg1, arg2, …) would be non-sensical. Which attribute should be set while the rest are ignored? The first one or the last one? I decided to disallow it altogether.
23 24 25 26 |
# File 'lib/union.rb', line 23 def initialize super define_union_setters end |
Instance Method Details
#[]=(symbol, value) ⇒ Object
Identical to Struct attribute assignment, except that setting one instance variable sets all other instance variables to nil. Also, you cannot use a numeric index. You must use a string or symbol.
Union.new('Human', :name, :age)
h = Union::Human.new
h[:name] = 'Daniel' # => #<struct Union::Human name="Daniel", age=nil>
h[:age] = 38 # => #<struct Union::Human name=nil, age=38>
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
# File 'lib/union.rb', line 38 def []=(symbol, value) # Validate that the symbol is a valid member symbol_str = symbol.to_s unless members.any? { |m| m.to_s == symbol_str } raise ArgumentError, "no member '#{symbol}' in union" end # Set the value for the specified member super(symbol, value) # Clear all other members members.each { |m| super(m, nil) unless m.to_s == symbol_str } value end |
#current_value ⇒ Object
Returns the current value (the value of the non-nil member) Returns nil if no member is set
Union.new('Human', :name, :age)
h = Union::Human.new
h.name = 'Daniel'
h.current_value # => 'Daniel'
74 75 76 77 |
# File 'lib/union.rb', line 74 def current_value member = which_member member ? self[member] : nil end |
#which_member ⇒ Object
Returns the name of the currently set member (the one with a non-nil value) Returns nil if no member is set
Union.new('Human', :name, :age)
h = Union::Human.new
h.name = 'Daniel'
h.which_member # => :name
62 63 64 |
# File 'lib/union.rb', line 62 def which_member members.find { |member| !self[member].nil? } end |