Class: Vissen::Input::Matcher

Inherits:
Object
  • Object
show all
Defined in:
lib/vissen/input/matcher.rb

Overview

The job of an input matcher is to match a raw message with a message class.

== Usage In the following example a matcher is setup to match aftertouch messages (on channel 0). Only data arrays of the correct length and content causes #match? to return true

matcher = Matcher.new(Message::Aftertouch) { |d| d[0] == 0xA0 }

matcher.match? [0xB0, 0, 0] # => false matcher.match? [0xA0, 0] # => false matcher.match? [0xA0, 0, 0] # => true

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(message_klass, &proc) ⇒ Matcher

Returns a new instance of Matcher.

Parameters:

  • message_klass (Message)

    the message class that should be used to parse the data that this matcher matches. The class constant DATA_LENGTH will be used to verify that the data has the correct length.

  • proc (#call)

    the block that will be called to match messages.

Raises:

  • (TypeError)


29
30
31
32
33
34
35
36
# File 'lib/vissen/input/matcher.rb', line 29

def initialize(message_klass, &proc)
  raise TypeError unless message_klass <= Message

  @klass = message_klass
  @rule  = proc

  freeze
end

Instance Attribute Details

#klassMessage (readonly)

Returns the message class responsible for the messages that this matcher matches.

Returns:

  • (Message)

    the message class responsible for the messages that this matcher matches.



22
23
24
# File 'lib/vissen/input/matcher.rb', line 22

def klass
  @klass
end

Instance Method Details

#match(obj) {|message| ... } ⇒ false, ...

Matches either a hash or a Message against the internal matching rule. If the object matches and is not a Message object a new instance will be created.

If a block is given the message will be yielded to it.

Parameters:

  • obj (Message, Hash)

    the message to be matched.

Yields:

  • (message)

Returns:

  • (false)

    if the object does not match.

  • (Object)

    the return value of the given block, if a block was given.

  • (Message)

    the given message if it is a Message or a new instance.



65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/vissen/input/matcher.rb', line 65

def match(obj)
  data = obj.fetch :data
  return false if data.length < @klass::DATA_LENGTH || !@rule.call(data)

  message =
    case obj
    when Message then obj
    when Hash then @klass.new data, obj.fetch(:timestamp)
    end

  return message unless block_given?
  yield message
end

#match?(obj) ⇒ true, false

Match either a byte array or a Message against the rule stored in the matcher.

Parameters:

  • obj (Hash, #to_a)

    the message data to match.

Returns:

  • (true, false)

    true if the data matches.

Raises:

  • (KeyError)

    if obj is a Hash but does not include the :data key.



46
47
48
49
50
51
# File 'lib/vissen/input/matcher.rb', line 46

def match?(obj)
  data = obj.is_a?(Hash) ? obj.fetch(:data) : obj.to_a

  return false if data.length < @klass::DATA_LENGTH
  @rule.call data
end