cinchrb / cinch

The IRC Bot Building Framework
http://www.rubydoc.info/gems/cinch
MIT License
1k stars 180 forks source link

elegant way to respond to one of two words #231

Closed TheNotary closed 8 years ago

TheNotary commented 8 years ago

For instance, I'd like a bot to respond to !help and !h in the same way.

on(:message, /^!home/) { |m| respond_to_home(m) }
on(:message, /^!h(\s+|$)/)    { |m| respond_to_home(m) }

on(:message, /^!heat/) { |m| respond_to_heat(m) }

I don't mind that approach and it works for now, but some of the below usages might be more fun.

on :message, [/^!home/, /^!h(\s+|$)/] do |m|
  # code_goes_here
end

This method uses less markup, but requires that the Cinch::Handler initializer do a check against the last argument to see if it's a hash or a block.

on :message, /^!home/  { |m| respond_to_home(m) }
on :message, /^!h(\s+|$)/     { |m| respond_to_home(m) }
jhass commented 8 years ago

Why not on(:message, /^!(?:home|h)(?=\s|$)/) { |m| respond_to_home(m) } ?

TheNotary commented 8 years ago

Ughh... I edited it to make it more authentic (the !home alias can now be used like !h help) but I'm really starting to notice the ugliness of regex now.

Hey, thanks @jhass, that just popped on my screen.. I should have made my update into a new post. To address your question, in an attempt to maintain clairity of what messages are being caught, I'd lean towards multiple regex statements than a single harder to read one. But as I've demonstrated to myself, ^!h(\s+|$) really doesn't jump out as a clear regex (for the record, it once looked like /^!h/ but that mis-fired against commands like !heather).

TheNotary commented 8 years ago

I'm a bit over caffeinated and it's starting to become apparent that I'm procrastinating a little bit. Theoretically, the regular expressions could be avoided in a similar way to how Thor does away with them.

class Routes < Cinch
  desc "home", 'use this command to set your home town'
  def hello(home)
    LogicThing.home(home)
    m.reply "Your home is now set to #{home}"
  end
  map :h => :hello
end

But alas, I don't think anyone has free time/ energy/ or actual needs toward implementing something like that (I took a time boxed peaked into Thor's code and determined that jacking their code and merging it into a Cinch branch wouldn't be a quick task).

I wouldn't mind working on solving it so that there was block checking, that looks pretty simple to do and would add clarity if anyone else thought that looked cool.

e.g.

on :message, /^!home/  { |m| respond_to_home(m) }
dominikh commented 8 years ago

A couple things of note here:

  1. the on syntax is only meant for very simple bots. For "real" bots, use the plugin system
  2. Cinch is in maintenance mode. We are very unlikely to add significant new APIs.
  3. The recommended way of using multiple commands for the same functionality is to have a method encapsulating the functionality, and have the individual handlers call that method. I.e. your initial solution.

If you want anything more fancy, implement it in the scope of your own project. You can write your own modules that you mix in that implement your own APIs.

TheNotary commented 8 years ago

Ah, that makes sense, I've been looking at the framework as a way to build monolithic apps rather than modular plugins. Thanks for all the pointers. I'll close this since match does what I was doing with on.