Kroki do utworzenia 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,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
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.
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 "<html><body>This is a test.</body></html>"
W Rubym istnieje specjalna biblioteka wspomagajaca pisanie skryptow dla CGI. Jesli mielibysmy formularz HTML z elementem <input>, 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 "<html><body>#{text.reverse}</body></html>"
Odchodzi sie od skryptow CGI z powodow wydajnosciowych i koniecznosci uruchamiania interpretatora Rubego dla kazdego odwolania.
# 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
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('<html><body><h1>Hello!</h1></body></html>') end end end s = Mongrel::HttpServer.new("0.0.0.0", "1234") s.register("/", BasicServer.new) s.run.join
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.
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 (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