class Alda::EventContainer
The class for objects containing an event.
Alda::EventContainer objects are literally everywhere if you are a heavy user of event list sugars. See Alda::EventList#method_missing.
Attributes
The repetition counts. nil if none.
Alda::Score.new do p((c*2).count) # => 2 p((d*3*5).count) # => 15 end
The contained Alda::Event object.
Alda::Score.new do p c.event.class # => Alda::Note p((e/g).event.class) # => Alda::Chord p((a b).event.class) # => Alda::Sequence end
When setting this attribute, on_containing is invoked.
The repetition labels. Empty if none.
Alda::Score.new do p((c%2).labels) # => [2] p((c%[2,4..6]).labels) # => [2, 4..6] end
Public Class Methods
Creates a new Alda::EventContainer. Invokes on_containing.
event is the Alda::Event object to be contained.
parent is the Alda::EventList object containing the event.
# File lib/alda-rb/event.rb, line 147 def initialize event, parent super() @event = event @labels = [] @count = 1 self.parent = parent on_containing end
Public Instance Methods
Marks alternative endings.
Alda::Score.new { (b a%1)*2 }.to_s # => "[b a'1]*2"
# File lib/alda-rb/event.rb, line 232 def % labels labels = [labels] unless labels.is_a? Array @labels.replace labels.to_a check_in_chord self end
Marks repetition.
For examples, see %.
# File lib/alda-rb/event.rb, line 218 def * num @count = (@count || 1) * num check_in_chord self end
If at first event is not an Alda::Part, makes event an Alda::Chord object.
Alda::Score.new { piano_; c/-e/g }.play # (plays the chord Cm)
This usage assumes that other is an Alda::EventContainer and will extract the contained event out from other. This will lose some information about other, such as count and labels, and potentially lead to confusing results.
Because the labels information about other is lost, the label on d disappears in the following example:
Alda::Score.new { c/(d%1) }.to_s # => "c/d"
The following example shows that the two ways of writing a chord with a label are equivalent: adding the label and then using slash, or using slash and then adding the label. This is because labels and count are retained while the event is updated when / is called.
Alda::Score.new { p c%1/d == c/d%1 }.to_s # (prints "true") => "c/d'1 c/d'1"
If at first event is an Alda::Part object, makes event a new Alda::Part object. The meaning is to play the two parts simultaneously.
Alda::Score.new { violin_/viola_/cello_; e; f; g}.play # (plays notes E, F, G with three instruments simultaneously)
# File lib/alda-rb/event.rb, line 188 def / other other.detach_from_parent @event = if @event.is_a? Alda::Part Alda::Part.new @event.names + other.event.names, other.event.arg else Alda::Chord.new @event, other.event end self end
Overrides Alda::Event#==. Returns true if other is an Alda::EventContainer object and event, count and labels are all equal (using ==).
Alda::Event#==
# File lib/alda-rb/event.rb, line 312 def == other super || other.is_a?(Alda::EventContainer) && @event == other.event && @count == other.count && @labels == other.labels end
This method is called in %, *, and parent=. It checks if parent is an Alda::Chord and warns about potential dangers. Returns true if there is no danger, and false otherwise.
Because Alda 2 does not support specifying alternative endings inside a chord (something like a'1/b) (alda-lang/alda#383), this method will warn about this if such thing happens and we are using Alda 2.
Alda.v2! Alda::Score.new { x{a%1;b} }.to_s # (warns) => "a'1/b"
This method will warn about repetitions inside a chord in both generations because the resultant Alda code is not valid.
Alda::Score.new { x{a*2;b} }.to_s # (warns) => "a*2/b"
# File lib/alda-rb/event.rb, line 263 def check_in_chord if @parent.is_a?(Alda::Event) && @parent.is_event_of?(Alda::Chord) Alda::Utils.warn 'alternative endings in chord not allowed in v2' if Alda.v2? && !@labels&.empty? Alda::Utils.warn 'repetitions in chord not allowed' if @count && @count != 1 false else true end end
Overrides Alda::Event#is_event_of?. Whether it is an event of the given class (klass) or the contained event is.
Alda::Event#is_event_of?
# File lib/alda-rb/event.rb, line 301 def is_event_of? klass super || @event.is_event_of?(klass) end
Calls method on event.
Note that if the method of event returns event itself, the method here returns the container itself.
Alda::Score.new do container = c p container.class # => Alda::EventContainer p container.respond_to? :pitch # => false p container.pitch # => "c" p container.respond_to? :+@ # => false p((+container).class) # => Alda::EventContainer p to_s # => "c+" end
# File lib/alda-rb/event.rb, line 335 def method_missing(...) result = @event.__send__(...) result == @event ? self : result end
Overrides Alda::Event#parent=. Sets the Alda::Event#parent of the container as well as that of event.
# File lib/alda-rb/event.rb, line 279 def parent= event @parent = event check_in_chord @event.parent = event end
Overrides Alda::Event#to_alda_code.
# File lib/alda-rb/event.rb, line 204 def to_alda_code result = @event.to_alda_code result.concat ?', @labels.map(&:to_alda_code).join(?,) unless @labels.empty? result.concat ?*, @count.to_alda_code if @count != 1 result end