===== Tworzenie pliku Gem ===== Kroki do utworzenia Gemu: - organizacja kodu i innych plikow w odpowiednia strukture, - Tworzymy folder z nazwa gemu (''string_extend'' w przypadku naszego ''string_extend.rb''), - ''lib'' - kod zwiazany z biblioteka, - ''pkg'' - tymczasowy katalog, w ktorym zostanie wygenerowany Gem, - ''test'' - testy jednostkowe, etc., - ''doc'' - dokumentacja, - ''bin'' - narzedzia i skrypty systemowe, - tworzenie pliku specyfikacyjnego z informacjami o Gemie (''string_extend.gemspec''), require 'rubygems' spec = Gem::Specification.new do |s| s.name = 'string_extend' s.version = '0.0.1' s.summary = "StringExtend adds useful features..." s.files = Dir.glob("**/**/**") s.test_files = Dir.glob("test/*_test.rb") s.author = "Your Name" s.email = "your-email-address@email.com" s.has_rdoc = false s.required_ruby_version = '>= 1.8.2' end - uzycie programu ''gem'' do stworzenia Gemu z plikow zrodlowych i specyfikacji: ''gem build string_extend.gemspec'' utworzy plik Gem ''string_extend-0.0.1.gem''. Jest tez prostszy sposob, za pomoca Gema ''newgem'': ''newgem your_lib_name''. ===== Udostepnianie aplikacji jako zewnetrznej uslugi ===== ==== CGI Scripts ==== Jedna z metod udostepniania swoich plikow Rubego jest wykorzystanie skryptow CGI. CGI to standard, umozliwiajacy serwerowi http uruchamiac programy i przesylac dane pomiedzy nimi a klientem. Plik CGI moglby wygladac tak: #!/usr/bin/ruby puts "Content-type: text/html\n\n" puts "This is a test." W Rubym istnieje specjalna biblioteka wspomagajaca pisanie skryptow dla CGI. Jesli mielibysmy formularz HTML z elementem '''', ktory wysylalby cos do naszego skryptu CGI, mozna do tych danych dostac sie tak: #!/usr/bin/ruby require 'cgi' cgi = CGI.new text = cgi['text'] puts cgi.header puts "#{text.reverse}" Odchodzi sie od skryptow CGI z powodow wydajnosciowych i koniecznosci uruchamiania interpretatora Rubego dla kazdego odwolania. ==== Serwery HTTP ==== === WEBrick === # webrick.rb require 'webrick' server = WEBrick::GenericServer.new(:Port => 1234) trap("INT") { server.shutdown } server.start do |socket| socket.puts Time.now end Duzo bardziej potezna technika zwiazana jest z serwletami, ktore istnieja w swojej wlasnej klasie i maja wiecej kontroli nad zadaniami i odpowiedziami do nich skierowanymi: # webrick_2.rb require 'webrick' class MyServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(request, response) response.status = 200 response.content_type = "text/plain" response.body = "Hello, world!" end end server = WEBrick::HTTPServer.new(:Port => 1234) server.mount "/", MyServlet trap("INT") { server.shutdown } server.start # webrick_3.rb require 'webrick' class MyNormalClass def MyNormalClass.add(a, b) a.to_i + b.to_i end def MyNormalClass.subtract(a, b) a.to_i - b.to_i end end class MyServlet < WEBrick::HTTPServlet::AbstractServlet def do_GET(request, response) if request.query['a'] && request.query['b'] a = request.query['a'] b = request.query['b'] response.status = 200 response.content_type = 'text/plain' result = nil case request.path when '/add' result = MyNormalClass.add(a, b) when '/subtract' result = MyNormalClass.subtract(a, b) else result = "No such method." end response.body = result.to_s + "\n" else response.status = 400 response.body = "No parameters, you n00b." end end end server = WEBrick::HTTPServer.new(:Port => 1234) server.mount '/', MyServlet trap('INT') { server.shutdown } server.start http://microjet.ath.cx/WebWiki/WEBrick.html === Mongrel === Mongrel to szybszy, stabilniejszy serwer HTTP. # mongrel.rb require 'rubygems' require 'mongrel' class BasicServer < Mongrel::HttpHandler def process(request, response) response.start(200) do |headers, output| headers["Content-Type"] = 'text/html' output.write('

Hello!

') end end end s = Mongrel::HttpServer.new("0.0.0.0", "1234") s.register("/", BasicServer.new) s.run.join
==== RPC ==== Tam, gdzie jeden program wykorzystuje procedury i metody udostepniane przez inny, mozna skorzystac z RPC (Remote Procedure Call). W Rubym mamy ''XML-RPC'', ''SOAP'' i ''Drb''. === XML-RPC === Protokół przesyla dane jako XML, do transportu wykorzystujac HTTP. Zaleta takiego rozwiazania jest to, ze mozna napisac kilka programow w roznych jezykach, a i tak beda one mogly sie dogadac ze soba. # xmlrpc_2.rb require 'xmlrpc/client' server = XMLRPC::Client.new2("http://www.rubyinside.com/book/xmlrpctest.cgi") ok, results = server.call2("sample.sumAndDifference", 5, 3) if ok puts results.inspect else puts results.faultCode puts results.faultString end Output: {"sum"=>8, "difference"=>2} Tworzenie serwera XMLRPC: # xmlrpc_server.rb require 'xmlrpc/server' server = XMLRPC::Server.new(1234) server.add_handler("sample.sumAndDifference") do |a, b| { "sum" => a.to_i + b.to_i, "difference" => a.to_i - b.to_i } end trap("INT") { server.shutdown } server.serve === DRb === DRb (Distributed Ruby) to biblioteka Rubego, na pierwszy rzut oka podobna do XML-RPC. Jesli komunikowac maja sie tylko programy napisane w Rubym, oferuje wiecej mozliwosci. Jest zorientowana obiektowo. Klient: # drb_client.rb require 'drb' remote_object = DRbObject.new nil, 'druby://sqbell-gentoo:45073' puts remote_object.some_method Serwer: # drb_server.rb require 'drb' class OurClass def some_method "Some test text." end end DRb.start_service nil, OurClass.new puts "DRb server running at #{DRb.uri}" trap("INT") {DRb.stop_service } DRb.thread.join