Class: SlackRubyBot::MVC::Controller::Base

Inherits:
Object
  • Object
show all
Includes:
ActiveSupport::Callbacks
Defined in:
lib/slack-ruby-bot/mvc/controller/base.rb

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, view) ⇒ Base

Returns a new instance of Base.



136
137
138
139
140
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 136

def initialize(model, view)
  @model = model
  @view = view
  self.class.register_controller(self)
end

Class Attribute Details

.abstractObject (readonly) Also known as: abstract?

Returns the value of attribute abstract.



8
9
10
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 8

def abstract
  @abstract
end

Instance Attribute Details

#clientObject (readonly)

Returns the value of attribute client.



134
135
136
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 134

def client
  @client
end

#dataObject (readonly)

Returns the value of attribute data.



134
135
136
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 134

def data
  @data
end

#matchObject (readonly)

Returns the value of attribute match.



134
135
136
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 134

def match
  @match
end

#modelObject (readonly)

Returns the value of attribute model.



134
135
136
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 134

def model
  @model
end

#viewObject (readonly)

Returns the value of attribute view.



134
135
136
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 134

def view
  @view
end

Class Method Details

.abstract!Object

Define a controller as abstract. See internal_methods for more details.



34
35
36
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 34

def abstract!
  @abstract = true
end

.aliasesObject



19
20
21
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 19

def aliases
  Base.instance_variable_get(:@aliases)
end

.alternate_name(original_name, *alias_names) ⇒ Object

Maps a controller method name to an alternate command name. Used in cases where a command can be called via multiple text strings.

Call this method after defining the original method.

Class.new(SlackRubyBot::MVC::Controller::Base) do
  def quxo_foo_bar
    client.say(channel: data.channel, text: "quxo foo bar: #{match[:expression]}")
  end
  # setup alias name after original method definition
  alternate_name :quxo_foo_bar, :another_text_string
end

This is equivalent to:

e.g.

command 'quxo foo bar', 'another text string' do |*args|
  ..
end


108
109
110
111
112
113
114
115
116
117
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 108

def alternate_name(original_name, *alias_names)
  command_name = convert_method_name_to_command_string(original_name)
  command_aliases = alias_names.map do |name|
    convert_method_name_to_command_string(name)
  end

  aliases[command_name] += command_aliases

  alias_names.each { |alias_name| alias_method(alias_name, original_name) }
end

.command_classObject



15
16
17
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 15

def command_class
  Base.instance_variable_get(:@command_class)
end

.controllersObject



11
12
13
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 11

def controllers
  Base.instance_variable_get(:@controllers)
end

.inherited(klass) ⇒ Object

:nodoc:



38
39
40
41
42
43
44
45
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 38

def inherited(klass) # :nodoc:
  # Define the abstract ivar on subclasses so that we don't get
  # uninitialized ivar warnings
  unless klass.instance_variable_defined?(:@abstract)
    klass.instance_variable_set(:@abstract, false)
  end
  super
end

.internal_methods(controller) ⇒ Object

A list of all internal methods for a controller. This finds the first abstract superclass of a controller, and gets a list of all public instance methods on that abstract class. Public instance methods of a controller would normally be considered action methods, so methods declared on abstract classes are being removed. (Controller::Base is defined as abstract)



84
85
86
87
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 84

def internal_methods(controller)
  controller = controller.superclass until controller.abstract?
  controller.public_instance_methods(true)
end

.register_controller(controller) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 47

def register_controller(controller)
  # Only used to keep a reference around so the instance object doesn't get garbage collected
  Base.instance_variable_set(:@controllers, []) unless controllers
  Base.instance_variable_set(:@aliases, Hash.new { |h, k| h[k] = [] }) unless aliases
  controller_ary = Base.instance_variable_get(:@controllers)
  controller_ary << controller
  klass = controller.class

  methods = (klass.public_instance_methods(true) -
             # Except for public instance methods of Base and its ancestors
             internal_methods(klass) +
             # Be sure to include shadowed public instance methods of this class
             klass.public_instance_methods(false)).uniq.map(&:to_s)

  methods.each do |name|
    next if name[0] == '_'
    commands = lookup_command_name(name)

    # Generates a command for each controller method *and* its aliases
    commands.each do |command_string|
      # sprinkle a little syntactic sugar on top of existing `command` infrastructure
      command_class.class_eval do
        command command_string do |client, data, match|
          controller.use_args(client, data, match)
          controller.call_command
        end
      end
    end
  end
end

.reset!Object



23
24
25
26
27
28
29
30
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 23

def reset!
  # Remove any earlier anonymous classes from prior calls so we don't leak them
  Commands::Base.command_classes.delete(Controller::Base.command_class) if Base.command_class

  # Create anonymous class to hold our #commands; required by SlackRubyBot::Commands::Base
  Base.instance_variable_set(:@command_class, Class.new(SlackRubyBot::Commands::Base))
  Base.instance_variable_set(:@controllers, [])
end

Instance Method Details

#call_commandObject

Determine the command issued and call the corresponding instance method



153
154
155
156
157
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 153

def call_command
  verb = match.captures[match.names.index('command')]
  verb = normalize_command_string(verb)
  public_send(verb)
end

#use_args(client, data, match) ⇒ Object

Hand off the latest updated objects to the model and view and update our client, data, and match accessors.



144
145
146
147
148
149
150
# File 'lib/slack-ruby-bot/mvc/controller/base.rb', line 144

def use_args(client, data, match)
  @client = client
  @data = data
  @match = match
  model.use_args(client, data, match)
  view.use_args(client, data, match)
end