ã©ãã¯ãšã¯ïŒ
rack gemã®äœè
ã§ããChristian Neukirchenã«ãããšãRubyããµããŒãããWebãµãŒããŒïŒWEBrickãMongrelãªã©ïŒãšruby Webãã¬ãŒã ã¯ãŒã¯ïŒRailsãSinatraãªã©ïŒãæ¥ç¶ããããã®æå°éã®APIãæäŸããããã«äœæãããŸããã
Sinatraãªã©ã®ãã¬ãŒã ã¯ãŒã¯ã¯ãã©ãã¯ã®äžã«æ§ç¯ãããããWebã¢ããªã±ãŒã·ã§ã³ãµãŒããŒãæ¥ç¶ã§ããããã«ããã©ãã¯ã€ã³ã¿ãŒãã§ã€ã¹ãåããŠããŸãã
ã©ãã¯ã®ç®çã¯åçŽã§ã-HTTPãªã¯ãšã¹ãã®åŠçãç°¡åã«ãªããŸãã
HTTPã¯åçŽãªãããã³ã«ã§ããåºæ¬çã«ããµãŒããŒã«éä¿¡ãããã¯ã©ã€ã¢ã³ãã«è¿ãããããŒã¿ã®åœ¢åŒãèšè¿°ããŸãã HTTPèŠæ±ãšHTTPå¿çã®æ§é ã¯éåžžã«äŒŒãŠããŸãã HTTPãªã¯ãšã¹ãã¯ãã¡ãœãããšãªãœãŒã¹ã®ãã¢ãäžé£ã®ããããŒããªã¯ãšã¹ãæ¬æã§æ§æãããããªãã«ã§ããäžæ¹ãHTTP HTTPã¬ã¹ãã³ã¹ã¯ãã¬ã¹ãã³ã¹ã³ãŒããäžé£ã®ããããŒããªãã·ã§ã³ã®ã¬ã¹ãã³ã¹æ¬æã§æ§æãããŸãã
Mapping Rackã¯ããã«è¿ãã§ãã Rackã¢ããªã±ãŒã·ã§ã³ã¯ãåäžã®åŒæ°ïŒç°å¢ïŒãåããã¹ããŒã¿ã¹ãããããŒãå¿çæ¬æã®3ã€ã®èŠçŽ ã®é
åãè¿ãåŒã³åºãã¡ãœãããæã€ã«ããŒãªããžã§ã¯ãã§ãã
ã©ãã¯ã«ã¯ããã³ãã©ãŒãšã¢ããã¿ãŒãå«ãŸããŠããŸãã åè
ã¯Ruby WebãµãŒããŒã«æ¥ç¶ããåŸè
ã¯ãã¬ãŒã ã¯ãŒã¯ã«æ¥ç¶ããŸãã

ããã«ãŠã§ã¢ã䜿çšãããšãã¢ããªã±ãŒã·ã§ã³ã®ããŒãºã«åãããŠã©ãã¯ã倿Žã§ããŸãã ã©ãã¯ããã«ãŠã§ã¢ã®äž»ãªèãæ¹ã¯ãèŠæ±ãã¢ããªã±ãŒã·ã§ã³ã«å
¥ãåã«åŠçããå¿çãåŠçããŠããã¯ã©ã€ã¢ã³ãã«è¿ãããšã§ãã
ããã¥ã¡ã³ã
rack.rubyforge.org/docã©ãã¯ãèšçœ®
ãã®èšäºã«èšèŒãããŠãããã®ã¯ãã¹ãŠãWindowsã«ã€ã³ã¹ããŒã«ãããruby 1.9.2ã§ãã¹ããããŠããããšã«æ³šæããŠãã ããïŒ
host- master-
ãããPerã ïŒã
ã©ãã¯ãèšçœ®ãããŠããã確èªããŠãã ããã ãããè¡ãã«ã¯ãã³ã³ãœãŒã«ãéããŸãã
# irb --simple-prompt
>> require 'rack'
=> true
requireãtrueãè¿ãå Žåãã©ãã¯ãåãä»ããããŠããŸãã ããããªããšã次ã®ãããªãšã©ãŒã¡ãã»ãŒãžã衚瀺ãããŸãã
LoadError: no such file to load -- rack
ããã¯ãgem install rackã³ãã³ãã«ãã£ãŠç°¡åã«ä¿®æ£ãããŸãã
procãªããžã§ã¯ãã®ã¯ã€ãã¯ãã¢ãŒ
procãªããžã§ã¯ããèŠããŠããŸããïŒ ã«ããŒã§ã¯ããããã¯ã¯ãªããžã§ã¯ãã§ã¯ãããŸããããProcã¯ã©ã¹ã®ãªããžã§ã¯ãã«å€æã§ããŸãã ããã¯ãObjectã¯ã©ã¹ã®ã©ã ãã¡ãœãããåŒã³åºãããšã§å®è¡ã§ããŸãã ã©ã ãã䜿çšããŠäœæããããããã¯ã¯ãã«ããŒã¡ãœããã®ããã«åäœããŸãã ãŸããProcã¯ã©ã¹ã«ã¯callã¡ãœããããããå®è¡ã®ããã«ãããã¯ãåŒã³åºããŸãã
>> my_rack_proc = lambda {puts 'Rack Intro'}
=> #<Proc:0x1fc9038@(irb):2(lambda)>
>> # method call invokes the block
?> my_rack_proc.call
Rack Intro
=> nil
æãåçŽãªã©ãã¯ã¢ããªã±ãŒã·ã§ã³-my_rack_proc
æ¢ã«è¿°ã¹ãããã«ãã©ãã¯ã¢ããªã±ãŒã·ã§ã³ã¯ãåŒã³åºãã¡ãœããã«å¿çãããªããžã§ã¯ãïŒã¯ã©ã¹ã§ã¯ãªãïŒã§ããã1ã€ã®åŒæ°-ç°å¢ïŒç°å¢
ã§ããããŸã- çŽ ïŒãåã
ãŸã ã ç°å¢ã¯Hashã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã§ãªããã°ãªããŸããã ã¢ããªã±ãŒã·ã§ã³ã¯ã3ã€ã®å€ã®é
åãè¿ãå¿
èŠããããŸãïŒã¹ããŒã¿ã¹ã³ãŒãïŒ100以äžïŒãããããŒïŒããã·ã¥ïŒãããã³æ¬æïŒéåžžãæ¬æã¯æååã®é
åãã¢ããªã±ãŒã·ã§ã³ã€ã³ã¹ã¿ã³ã¹ããŸãã¯ãã¡ã€ã«ã§ããå¿çæ¬æã¯åã¡ãœããã«å¿çããæååå€ã®ã¿ãåºåããå¿
èŠããããŸãïŒã æ°ããprocãªããžã§ã¯ããäœæããŸãã
>> my_rack_proc = lambda { |env| [200, {}, ["Hello. The time is #{Time.now}"]] }
=> # <Proc:0x1f4c358@(irb):5(lambda)>
ããã§ãmy_rack_procãåŒã³åºãããšãã§ããŸãã
>> my_rack_proc.call({})
=> [200, {}, ["Hello. The time is 2011-10-24 09:18:56 +0530"]]
my_rack_procã¯ãåäžã©ã€ã³ã®ã©ãã¯ã§ãã
äžèšã®äŸã§ã¯ãããããŒã«ç©ºã®ããã·ã¥ã䜿çšããŸããã 代ããã«ã次ã®ããã«ããããŒã«äœããå
¥ããŸãããã
>> my_rack_proc = lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
=> #<Proc:0x1f4c358@(irb):5(lambda)>
>> my_rack_proc.call({})
=> [200, {"Content-Type" => "text/plain"}, ["Hello. The time is 2011-10-24 09:18:56 +0530"]]
ä»»æã®ãã³ãã©ãŒã䜿çšããŠã©ãã¯ã¢ããªã±ãŒã·ã§ã³ãå®è¡ã§ããŸãã
ã©ã®ã¿ã€ãã®ãã³ãã©ãŒãå©çšå¯èœãèŠãŠã¿ãŸãããïŒ
>> Rack::Handler.constants
=> [:CGI, :FastCGI, :Mongrel, :EventedMongrel, :SwiftipliedMongrel, :WEBrick, :LSWS, :SCGI, :Thin]
WEBrickã䜿çšããã«ã¯ïŒããã©ã«ãã§ã¯WEBrickã¯Rubyã§ã€ã³ã¹ããŒã«ããããµãŒããŒã§ãïŒã次ã®ããã«å
¥åããŸãã
>> Rack::Handler::WEBrick
=> Rack::Handler::WEBrick
ããããã¹ãŠã®ãã³ãã©ãŒã«ã¯ãã©ãã¯ã¢ããªã±ãŒã·ã§ã³ãèµ·åããrunã¡ãœããããããŸãã
>> Rack::Handler::WEBrick.run my_rack_proc
[2011-10-24 10:00:45] INFO WEBrick 1.3.1
[2011-10-24 10:00:45] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 10:00:45] INFO WEBrick::HTTPServer#start: pid=1788 port=80
ãã©ãŠã¶ã§
localhostããŒãžãéããšã次ã®ãããªè¡ã衚瀺ãããŸãã
ããã«ã¡ã¯ æéã¯2011-10-24 10:02:20 +0530
æ³šïŒæ¢ã«ããŒã80ã§äœããå®è¡ããŠããå Žåã¯ãå¥ã®ããŒãã§ã¢ããªã±ãŒã·ã§ã³ãå®è¡ã§ããŸãã>> Rack::Handler::WEBrick.run my_rack_proc, :Port => 9876
[2011-10-24 11:32:21] INFO WEBrick 1.3.1
[2011-10-24 11:32:21] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 11:32:21] INFO WEBrick::HTTPServer # start: pid = 480 port = 9876
å¥ã®ã©ãã¯ã¢ããªã±ãŒã·ã§ã³ã¯my_methodã§ã
ã©ãã¯ã¢ããªã±ãŒã·ã§ã³ã¯å¿
ãããã©ã ãã§ã¯ãããŸããã ã¡ãœããã«ããããšãã§ããŸãã
>> def my_method env
>> [200, {}, ["method called"]]
>> end
=> nil
>> Rack::Handler::WEBrick.run method(:my_method)
[2011-10-24 14:32:05] INFO WEBrick 1.3.1
[2011-10-24 14:32:05] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 14:32:05] INFO WEBrick::HTTPServer#start: pid=1644 port=80
localhostã§åã³è¡šç€ºãããŸãïŒ
åŒã³åºãããã¡ãœãã
ã¡ãœãããªããžã§ã¯ãã¯
ObjectïŒã¡ãœããã䜿çšããŠäœæãããŸãã ãããã¯ç¹å®ã®ãªããžã§ã¯ãã«é¢é£ä»ããããŠããŸãïŒã¯ã©ã¹ã ãã§ã¯ãããŸããïŒã ãªããžã§ã¯ãå
ã®ã¡ãœãããåŒã³åºãããã«äœ¿çšã§ããŸãã
Method.callã¯ãæå®ãããåŒæ°ã§ã¡ãœããïŒ
Ohãhackãhack ...- çŽPerã ïŒãåŒã³åºããåŒã³åºãããã¡ãœãããè¿ãå€ãè¿ãã¡ãœããã§ãã
ã©ãã¯ã¢ããã䜿çšãã
å®ç³ã©ãã¯ã«ã¯ãéçºè
ã®ç掻ãç°¡çŽ åãã䟿å©ãªéšåã倿°ä»å±ããŠããŸãã ãããã®éšåã®1ã€ãã©ãã¯ã¢ããã§ãã
Rackupã¯ãã©ãã¯ã¢ããªã±ãŒã·ã§ã³ãèµ·åããããã®äŸ¿å©ãªããŒã«ã§ãã Rackupèªäœãå®è¡ç°å¢ã決å®ããFastCGIãCGIããŸãã¯MongrelãŸãã¯WEBrickã䜿çšããã¹ã¿ã³ãã¢ãã³ãšããŠã¢ããªã±ãŒã·ã§ã³ãå®è¡ããŸã-ãã¹ãŠåãæ§æã§ãã
rackupã䜿çšããã«ã¯ãæ§æãã¡ã€ã«ãäœæããå¿
èŠããããŸãã æ
£äŸã«ããããã®æ§æã«ã¯.ruæ¡åŒµåã䜿çšããå¿
èŠããããŸãã ããã©ã«ãã§ã¯ãã©ãã¯ã¢ããã¯ããŒã9292ã§éå§ãããŸãã
以äžãå«ãconfig.ruãã¡ã€ã«ãäœæããŸãããã
run lambda { |env| [200, {"Content-Type" => "text/plain"}, ["Hello. The time is #{Time.now}"]] }
ãã®ãã¡ã€ã«ã«ã¯
runãšããåèª
ãå«ãŸããŠã
ãŸã ãããã¯ã.callã¡ãœããã«å¿çãããã¹ãŠã®ãã®ããåŒã³åºãããšãã§ããŸãã
config.ruãã¡ã€ã«ããããã©ã«ããŒã§ã©ãã¯ã¢ããªã±ãŒã·ã§ã³ãèµ·åããã«ã¯ã次ã®ããã«å
¥åããŸãã
$ rackup config.ru
[2011-10-24 15:18:03] INFO WEBrick 1.3.1
[2011-10-24 15:18:03] INFO ruby 1.9.2 (2011-07-09) [i386-mingw32]
[2011-10-24 15:18:03] INFO WEBrick::HTTPServer # start: pid = 3304 port = 9292
ããã§ã
localhost ïŒ9292 /ã§ã次ã®ããŒãžãåã³è¡šç€ºãããŸãã
Hello. The time is 2011-10-24 15:18:10 +0530
ã¢ããªã±ãŒã·ã§ã³ãconfig.ruãã¡ã€ã«ããmy_app.rbã«ç§»åããŸãããã
config.ruã倿ŽããŸãã
require './my_app' run MyApp.new
ããã§ããrackup config.ruãã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãåã³èµ·åããããŒãžããã©ãŠã¶ã«éä¿¡ããããã©ããã確èªã§ããŸãã
Herokuã«ã©ãã¯ã¢ããªã±ãŒã·ã§ã³ããããã€ããŸãã
ïŒãã®èšäºã®äžéšã¯ãWindowsã«gitãã€ã³ã¹ããŒã«ããherokuã«å±éããããšã説æããŠãããããå·é
·ã«åãåãããŸãããèšäºèªäœãšã¯é¢ä¿ãããŸãããèå³ãããå Žåã¯ãå
ã®èšäºïŒ çŽPer ïŒã§èªãããšãã§ããŸãïŒã©ãã¯ããã«ãŠã§ã¢ã®äœ¿çš
ãµãŒããŒãšãã¬ãŒã ã¯ãŒã¯ã®éã§ãããã«ãŠã§ã¢ã䜿çšããŠããŒãºã«åãããŠã©ãã¯ãæ§æã§ããããšã¯åè¿°ããŸããã
Rackupã¯ãããã«ãŠã§ã¢ãåãå
¥ããæ¹æ³ã䜿çšããŸãã çµã¿èŸŒã¿ã®ã©ãã¯ããã«ãŠã§ã¢ã®1ã€ã䜿çšããŠã¿ãŸãããã
config.ruãŸãã¯my_app.rbãã¡ã€ã«ã倿Žãããã³ã«ãWEBrickãµãŒããŒãåèµ·åããå¿
èŠãããããšã«æ³šæããŠãã ããã ããã¯ããã«ãŠã§ã¢Rack :: Reloaderã䜿çšããŠåé¿ã§ããŸãã config.ruãç·šéããŸãã
require './my_app' use Rack::Reloader run MyApp.new
ãããŠãmy_app.rbïŒ
ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããã©ãŠã¶ã§ããŒãžãéããŸãã ããã¹ãããäžçäžã®Hello Rackåå è
ïŒããããäžçäžã®Hello Rackåå è
ïŒãã«å€æŽããŸãããã©ãŠã¶ãŒã§ããŒãžãæŽæ°ãããšãWebãµãŒããŒãåèµ·åããã«ç·šéããããã¹ãã衚瀺ãããŸãã
ç¬èªã®ããã«ãŠã§ã¢ã®äœæ
ããã«ãŠã§ã¢ã¯ãå®éã«ã¯åžžã«å
éšã¢ããªã±ãŒã·ã§ã³ãã©ããããã®ã«åœ¹ç«ã¡ãŸãã
httpå¿çã®æ¬æã«ããã¹ãã远å ããæãåçŽãªããã«ãŠã§ã¢ãäœæããŸãããã ãããè¡ãã«ã¯ãMyRackMiddlewareã¯ã©ã¹ãäœæããŸãã
class MyRackMiddleware def initialize(appl) @appl = appl end def call(env) end end
äžèšã®ã³ãŒãã§ã¯ãæåã®å¿çæ¬æãååŸããããã«ãMyRackMiddlewareã¯ã©ã¹ãåæåããã¢ããªã±ãŒã·ã§ã³ïŒapplïŒãããã«æž¡ããŸãã
.callã¡ãœããã倿ŽããŸãã
def call(env) status, headers, body = @appl.call(env)
äžèšã®ã³ãŒãã§ã¯ãå
ã®å¿çæ¬æã«ã¢ã¯ã»ã¹ã§ããŸãããããã倿Žã§ããŸãã ã©ãã¯ã¯ãæ¬äœãã¹ããªã³ã°ã§ããããšãä¿èšŒããŸããã ãªããžã§ã¯ãã«ããããšãã§ããŸããã.eachã¡ãœãããåŒã³åºããšãè¿ããããã®ã¯ãã¹ãŠæååã«ãªããŸãã ããã.callã¡ãœããã§äœ¿çšããŸãã
def call(env) status, headers, body = @appl.call(env) append_s = "... greetings from RubyLearning!!" [status, headers, body << append_s] end
config.ruãã¡ã€ã«ã倿ŽããŸãã
require './my_app' require './myrackmiddleware' use Rack::Reloader use MyRackMiddleware run MyApp.new
ã¢ããªã±ãŒã·ã§ã³ãèµ·åãããšããã©ãŠã¶ãŒã«ãäžçäžã®Hello Rackåå è
... RubyLearningããã®æšæ¶!!ãã衚瀺ãããŸãã
ã©ãã¯ãšã·ããã©
æåŸã«ãsinatraãã¬ãŒã ã¯ãŒã¯ã§ã©ãã¯ã䜿çšããç°¡åãªäŸã瀺ããŸãã
ã©ãã¯ããã«ãŠã§ã¢ã䜿çšããç°¡åãªã¢ããªã±ãŒã·ã§ã³my_sinatra.rbãäœæããŸãããã
require 'sinatra' require './rackmiddleware' use RackMiddleware get '/' do 'Welcome to all' end
次ã«ãã¢ããªã±ãŒã·ã§ã³ããã®èŠæ±ãåŠçããããã«ã³ã³ãœãŒã«æéã«æžã蟌ãåçŽãªããã«ãŠã§ã¢ã¯ã©ã¹ãé
眮ããŸãããã rackmiddleware.rbãã¡ã€ã«ãäœæããŸãã
class RackMiddleware def initialize(appl) @appl = appl end def call(env) start = Time.now status, headers, body = @appl.call(env)
config.ruãã¡ã€ã«ã倿ŽããŸãã
require "./my_sinatra" run Sinatra::Application
ïŒ
次ã¯ãHerokaã«ãããã€ããæ¹æ³ãgitã䜿çšããæ¹æ³ãªã©ã®ããã¹ããããã¯ã§ããããããããšã¯æããªãã§ããã- çŽã ïŒ
ããã§ãåãªã¯ãšã¹ãã«å¯ŸããŠã¢ããªã±ãŒã·ã§ã³ãèµ·åããåŸããããæ¬¡ã®å
容ã®è¡ãã³ã³ãœãŒã«ã«æžã蟌ãŸããŸãã
?[36m2011-10-26T05:40:06+00:00 app[web.1]:?[0m *** Response Time ***: 0.000297385
以äžã§ãã ã©ãã¯ãžã®ãã®ãšã³ããªã楜ããã ããšãé¡ã£ãŠããŸãã ããããŒã©ããã³ã°ïŒ