===== 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