简体   繁体   English

在Ruby中'<<'运算符有什么用

[英]What are the uses of the '<<' operator in ruby

I have this sample code, which is essentially just a few basic classes for working with mdii files 我有这个示例代码,从本质上来说,这只是用于mdii文件的一些基本类。

class Array
    def to_midi(file, note_length='eighth')

        midi_max = 108.0
        midi_min = 21.0

        low, high = min, max
        song = MIDI::Sequence.new

        # Create a new track to hold the melody, running at 120 beats per minute.
        song.tracks << (melody = MIDI::Track.new(song))
        melody.events << MIDI::Tempo.new(MIDI::Tempo.bpm_to_mpq(120))

        # Tell channel zero to use the "piano" sound.
        melody.events << MIDI::ProgramChange.new(0, 0)

        # Create a series of note events that play on channel zero.
        each do |number|
            midi_note = (midi_min + ((number-midi_min) * (midi_max-low)/high)).to_i
            melody.events << MIDI::NoteOnEvent.new(0, midi_note, 127, 0)
            melody.events << MIDI::NoteOffEvent.new(0, midi_note, 127,
            song.note_to_delta(note_length))
        end

        open(file, 'w') { |f| song.write(f) }
    end
end
class TimedTrack < MIDI::Track
    MIDDLE_C = 60
    @@channel_counter=0

    def initialize(number, song)
        super(number)
        @sequence = song
        @time = 0
        @channel = @@channel_counter
        @@channel_counter += 1
    end

    # Tell this track's channel to use the given instrument, and
    # also set the track's instrument display name.
    def instrument=(instrument)
        @events << MIDI::ProgramChange.new(@channel, instrument)
        super(MIDI::GM_PATCH_NAMES[instrument])
    end

      # Add one or more notes to sound simultaneously. Increments the per-track
      # timer so that subsequent notes will sound after this one finishes.
    def add_notes(offsets, velocity=127, duration='quarter')
        offsets = [offsets] unless offsets.respond_to? :each
        offsets.each do |offset|
            event(MIDI::NoteOnEvent.new(@channel, MIDDLE_C + offset, velocity))
        end
        @time += @sequence.note_to_delta(duration)
        offsets.each do |offset|
            event(MIDI::NoteOffEvent.new(@channel, MIDDLE_C + offset, velocity))
        end
        recalc_delta_from_times
    end

      # Uses add_notes to sound a chord (a major triad in root position), using the
      # given note as the low note. Like add_notes, increments the per-track timer.
    def add_major_triad(low_note, velocity=127, duration='quarter')
        add_notes([0, 4, 7].collect { |x| x + low_note }, velocity, duration)
    end

    private

        def event(event)
            @events << event
            event.time_from_start = @time
        end
end

most of it makes perfect sense to me except for the lines that use the << operator, from all of my research the only reason to use a << is when your defining a class that will be a singleton. 除了使用<<运算符的行外,大多数代码对我来说都是完全有意义的,根据我的所有研究,使用<<的唯一原因是在您定义一个单例类时。 So in what way specifically is the << being used in this code? 那么在此代码中使用<<具体方式是什么?

From https://github.com/jimm/midilib : https://github.com/jimm/midilib
MIDI::Track is a track that contains an array of events. MIDI::Track是包含事件数组的轨道。

So with << you're adding events to your track. 因此,通过<<将事件添加到轨道中。 It is the same as melody.events.push(MIDI::NoteOnEvent.new(0, midi_note, 127, 0)) 它与melody.events.push(MIDI::NoteOnEvent.new(0, midi_note, 127, 0))

<< could also be used for bit shifting operations <<也可用于移位操作

http://calleerlandsson.com/2014/02/06/rubys-bitwise-operators/ http://calleerlandsson.com/2014/02/06/rubys-bitwise-operators/

<< operator may be used either for bitwise operations (quite unlikely here) or may be overloaded inside the class to match some behavior. <<运算符既可以用于按位运算(在这里不太可能),也可以在类内部重载以匹配某些行为。 In this case there is (probably) an Array object and thus the event is pushed into the @events array via this operator. 在这种情况下,(可能)有一个Array对象,因此该event通过此运算符推入@events数组。 More info about this use case can be found here . 有关此用例的更多信息,请参见此处

Take notice, that in future you can bump into other situations where this operator is used and not everytime it will mean same thing - it depends on library creator. 请注意,将来您可能会遇到使用该运算符的其他情况,而不是每次都意味着相同的情况-它取决于库创建者。 The other use case that comes into mind right now can be ActiveRecord Relationships, as has_many where also you can use this operator to immediately push an object to relationship and save. 现在想到的另一个用例可以是ActiveRecord Relationships,例如has_many ,您还可以使用此运算符将对象立即推入关系并保存。 More info about this one can be found in api docs here . 可以在api文档中找到有关此内容的更多信息。 Quick sample: 快速样本:

class User < ActiveRecord::Base
  has_many :posts
end

class Post < ActiveRecord::Base
  belongs_to :user
end

And then somewhere in code you can use: 然后可以在代码中的某处使用:

@post = Post.find(10)
@user = User.find(1)
@user.posts << @post
# automatically save the @post object with updated foreign key

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM