Applicazioni multipiattaforma 100% GUI-Indipendent
Può capitare di dover realizzare programmi che siano utilizzabili con diverse interfacce grafiche, in Ruby ci sono diversi stratagemmi per farlo e al primo posto troviamo i blocchi, ecco un programmino d'esempio che funzione da gtk o console.
L'idea di base è che tutti i controlli dati vengono fatti dalla classe interna, mentre le interfacce si limitino solo a fare input/output; probabilmente questo approccio non va bene in tutti i casi, ma se si usano pochi semplici widget fa la sua bella figura.
Ho deciso di usare i metodi "error" e "notify", per semplicità, ma si sarebbero potute utilizzare anche le eccezioni; stesso discorso per l'alert. Gtk::Dialog sarebbe il widget giusto, ma rischierebbe di creare confusione.
Si esegue con:
ruby esempio.rb (Console) o ruby esempio.rb --gtk (Gtk)
#!/usr/bin/ruby
=begin
== esempio.rb ==
Una semplice implementazione di oggetti indipendenti dall'interfaccia grafica/console
oOo. http://assente.altervista.org .oOo
=end
# Oggetto principale GUI-indipendent
class List
def initialize()
@a=[]
end
def add(value)
# vari controlli sull'input
if value==""
error("Valore nullo")
elsif value=~/[a-zA-Z]/
error("Le lettere non sono ammesse")
elsif value=~/[0-9]/
@a << value
notify("'#{value}' inserito")
end
end
# yield viene sostituito con quello che passiamo a livello superiore,
# puts oppure @display.text+=, fantastico, no?
def show_all
@a.each { |value| yield value}
end
end
class ConsoleList < List
def initialize
super
puts "Console mode"
while true
puts "1: Aggiungi 2: Visualizza 3: Esci"
# toglie \n dall'input da terminale
choice=gets.strip
case (choice)
when "1" then add
when "2" then show_all
when "3" then exit
else
error("Scelta non valida")
end
end
end
def add
puts "Inserisci: "
# manda al metodo List#add vedi su
super(gets.strip)
end
# Richiamato da List
def error(text)
puts "!! #{text} !!"
end
def notify(text)
puts ">> #{text}"
end
def show_all
super{|v| puts "|#{v}|"}
end
end
class GtkList < List
require 'gtk2'
def initialize
super
puts "GUI mode"
Gtk.init
#Inizializzo i widget
@window=Gtk::Window.new
@container=Gtk::VBox.new
@entry=Gtk::Entry.new
@display=Gtk::Label.new
@button=Gtk::Button.new("Inserisci")
#Assegno gli eventi
@button.signal_connect("clicked"){add}
@entry.signal_connect("activate"){add}
@window.signal_connect("destroy"){exit}
#impacchetto
@container.add(@display).add(@entry).add(@display).add(@display).add(@button)
@window.add(@container)
@window.show_all
Gtk.main
end
def add
puts "Inserisci: "
super(@entry.text)
@entry.text=""
end
def error(text)
# Con più spazio estendetevi Gtk::Alert :-)
Gtk::Window.new.add(Gtk::Label.new("#{text}")).show_all
end
def notify(text)
# Non necessario
#Gtk::Window.new.add(Gtk::Label.new("#{text}")).show_all
show_all
end
def show_all
@display.text=""
super{|v| @display.text+=v+" "}
end
end
# Inizia qui
case(ARGV[0])
when nil: ConsoleList.new
when "--gtk": GtkList.new
end



il Ruby?
non nascondo che questo titolo mi ha un po' preso di sprovvista in quanto il Ruby non era menzionato.
Perchè scegliere Ruby anzichè wxWidgets in diverse configurazioni? (C++, Python o JavaScript)
Perchè non sviluppare un confronto in questo senso ed aggiungere altre proposte che possono esserci?
=)