初のRuboty Handlerです。
先日CodeIQのHubot問題で触ったこともありますので、言語ジェネレータ( https://github.com/cielavenir/codeiq_solutions/blob/master/codeiq2nd_intercal.rb )を題材にしてみました。
Intercalは変形xorを行って出力するので、そのやり方については↑の終端コメントを参照のこと。
URL
Base
ruboty-gen gem を使いました(ruboty-gen gem intercal_generator
)。
Handler
module Ruboty
module Handlers
class IntercalGenerator < Base
on /intercal (?<text>.*)/, name: 'intercal', description: 'generate intercal code'
def intercal(message)
Ruboty::IntercalGenerator::Actions::Generate.new(message).call
end
end
end
end
DSLのname
とメソッド名を一致させる必要があるようです(未確認)。
(?<text>.*?)
とかやると動きません。まあ、ミスる人は少ないとは思いますが。
Action
require 'stringio'
module Ruboty
module IntercalGenerator
module Actions
class Generate < Ruboty::Actions::Base
def call
ret=StringIO.new
last=0
siz=message[:text].bytes.to_a.size
please=(siz+3)/4-2
ret.puts "DO ,1 <- ##{siz}"
message[:text].each_byte.with_index{|e,i|
c = e
c = (c & 0x55) << 1 | (c & 0xaa) >> 1
c = (c & 0x33) << 2 | (c & 0xcc) >> 2
c = (c & 0x0f) << 4 | (c & 0xf0) >> 4
last2 = c
c = (last-c)&0xff
last = last2
ret.print 'PLEASE ' if i<=please
ret.puts "DO ,1 SUB ##{i+1} <- ##{c&0xff}"
}
ret.puts 'PLEASE READ OUT ,1'
ret.print 'PLEASE GIVE UP'
message.reply(ret.string)
end
end
end
end
end
この点について言及している入門サイトが少ない感じがしましたが、messageを呼ぶとHandlerのDSLに記述した正規表現から得られる連想配列(正確には[]でアクセスできるオブジェクト)が返ってくるようです。
テスト
OSXの場合、Shell Adapterにマルチバイト文字列を貼り付けようとするとこけるので、rb-readline gemを導入した上で、ruby -rrb-readline -S ruboty
と実行する必要がある。こういうところが地味にはまるんですよね…。
> ruboty intercal I ♥ CodeIQ.
DO ,1 <- #13
PLEASE DO ,1 SUB #1 <- #110
PLEASE DO ,1 SUB #2 <- #142
PLEASE DO ,1 SUB #3 <- #189
DO ,1 SUB #4 <- #174
DO ,1 SUB #5 <- #244
DO ,1 SUB #6 <- #161
DO ,1 SUB #7 <- #66
DO ,1 SUB #8 <- #204
DO ,1 SUB #9 <- #208
DO ,1 SUB #10 <- #128
DO ,1 SUB #11 <- #20
DO ,1 SUB #12 <- #8
DO ,1 SUB #13 <- #22
PLEASE READ OUT ,1
PLEASE GIVE UP
警告
WARN: Unresolved specs during Gem::Specification.reset:
json (>= 1.7.7, ~> 1.7)
WARN: Clearing out unresolved specs.
Please report a bug if this causes problems.
こんな感じの警告が出る。しかもjson 1.7.7は標準ライブラリのようなのでgem cleanup
もできない。
bundle exec ruboty
とすれば問題ない模様。ただしbundle exec ruby -rrb-readline -S ruboty
は効かないので、OSXの標準Rubyを使う場合は諦めましょう。無視する分には大丈夫なようですので。
最後に
体験記みたくなってしまいましたが、多分問題ないかと>_<
A言語/Brainf*ck
Whitespaceは出力させてもあまり意味が無いことに気が付きました。