Agenda
- Introducing to net-irc
- Applications using net-irc
- Citrus IRC BOT framework
- About the DSL (or something DSL-ish)
- DSL in the language
Introducing to net-irc
My IRC status
- irssi user
- window number -> 54 (not channel num)
- IRC addict
...
I want to watch all information by IRC.
- twitter...
- lingr...
- server log...
...
- Posting to mixi...
- Recent hatena stars...
- Posting to Hatena Haiku...
- etc.. etc..
...
But there were no library to write IRC server easily...
And I made it.
What is net-irc?
- Is IRC library
- Parser from RICE by akira yamada
- Has both Client and Server
Changes from RICE
- Violate RFC for practical issue
- Don't use observer design pattern
- Wrote prettily
Violate RFC
- no restriction on nick length
- RFC restrict nick length to 9 chars
- allow utf-8 nick
- allow multibyte string
- (extendable MODE parser)
- (working)
Don't use observer
- Observer pattern
- in the end, must write event dispatcher
- on_event is popular
- no more charms
Wrote prettily
Write to server socket:
post PRIVMSG, '#foo', 'msg' post NOTICE, '#foo', 'msg'
All commands are defined as constant.
Use RFC as reference instead of net-irc reference.
Sample Client
class SimpleClient < Net::IRC::Client
def on_privmsg(m)
super
post NOTICE, m[0], m[1] # echo
end
end
SimpleClient.new("host", 6667, {
:nick => "foobartest",
:user => "foobartest",
:real => "foobartest",
}).start
Sample Server
class Sample < Net::IRC::Server::Session
def on_privmsg(m)
super
post "foo!foo@host", NOTICE, m[0], m[1] # echo
end
end
Net::IRC::Server.new(opts[:host], opts[:port], Sample, opts).start
Applications using net-irc
mini-blog IRC gateways
- Twitter (tig.rb) like TIG
- Wassr (wig.rb)
- Nowa (nig.rb) すいませんまだ使ってません
Suitable for practical use!
Distributed with net-irc. (examples/)
Lingr IRC gateway
- Using Linger API
Suitable for practical use!
Distributed with net-irc. (examples/)
でもたまに切れる。
...
examples なのはテスト書くのがめんどうだから……
昨日書いたもの
demo
Citrus IRC BOT framework
http://coderepos.org/share/wiki/Citrus
- Has testing framework (using rspec)
- Supports gettext
- Has dynamic re-loading plugins
coderepos++
Citrus
- Sample: chokan @freenode (registered)
Citrus plugin
- Plugin tests are in same file!
- Use RSpec
- DummyCore class for test
Citrus plugin
class SimpleReply < Citrus::Plugin
def on_privmsg(prefix, channel, message)
# do...
end
end
test do
# run when test
describe SimpleReply do
before :all do
@core = DummyCore.new({})
@socket = @core.socket
@plugin = SimpleReply.new(@core, {
"SimpleReply" => { config }
})
end
it "should ..." do
end
end
end
About the DSL
It's DSL
# client post PRIVMSG, "#foo", "bar" # server post prefix, PRIVMSG, "#foo", "bar
Effective utilzation of Constant
PRIVMSG = 'PRIVMSG' NOTICE = 'NOTICE' ... RPL_WELCOME = '001'
I don't want to use String.
- It mades typo.
- It is not pretty.
DSL in the language
...
post PRIVMSG, "#foo", "bar"
DSL...?
Maybe not.
Often, I try to make DSL.
But I assessed that DSL is irrelevance for this library..
DSL bad example
- scrAPI
ebay_auction = Scraper.define do process "h3.ens>a", :description=>:text, :url=>"@href" process "td.ebcPr>span", :price=>:text process "div.ebPicture>a>img", :image=>"@src" result :description, :url, :price, :image end
Can't understand the purpose at first view.
某所で scrAPI なコードをメンテしたとき発狂しそうだった
DSL bad example - scrAPI
- what is second argument of process
- need to look the reference
- lerning cost > convenience
- mechanize and hpricot is better
DSL good examples
- Rake
- RSpec
DSL good examples - Rake
desc "Publish to RubyForge" task :rubyforge => [:rdoc, :package] do require 'rubyforge' Rake::RubyForgePublisher.new(RUBYFORGE_PROJECT, 'fobar').upload end
Good example of hash arrow to represent dependency.
DSL good examples - RSpec
obj.should == "foo" foo.should be_true
Easy to read, easy to write.
DSL good examples
- Rake
- RSpec
Can understand the purpose at first view!
So, DSL requires...
- Readable!
- not requires precedent
- Writable!
- not relying on reference
DSL's problems
- hard to trace process
- hard to know Class defining the method
- IT IS A LANGUAGE.
- It is difficult to design a language.
Any sufficiently designed DSL is indistinguishable from NEW language.
高度に発達した DSL は新言語と見分けがつかない
Think before using DSL!
End
Thank you