Ruby – ancora su file e directory

r9

Nel post precedente ho tralasciato parecchie cose su come gestire file e directory con Ruby. Ne è nata una discussione, credo sia il caso di approfondire l’argomento. Anche perché non ci sono cose nuove, non ancora affrontate nel corso.

Una cosa che ho dato per scontata e forse non lo è: in Ruby ci sono sempre diverse vie per fare una cosa, non so se è un bene o no, ma è la filosofia di Matz. Ancora: ci sono istruzioni che nel tempo cambiano; quello che era OK con la revisione x.y non vale più dalla z.0 in poi. Non proprio l’ideale, ma dobbiamo conviverci.

require e load

Le due istruzioni sembrano uguali, consentono entrambe di usare nello script corrente le risorse (oggetti, in Ruby tutto è un oggetto) definite al loro interno come se fossero nel file corrente. C’è però una grossa differenza: require va usato una sola volta gli oggetti vengono memorizzati mentre load è solo un modo per evitare il copia-incolla da un file a quello corrente, evitando di doverlo rifare quando si modifica l’originale; quindi può essere usato più volte nello stesso script (se uno è pasticcione, altrimenti non credo sia necessario).
Ecco un esempio minimo che usa sia require che load (loreq.rb):

#!/usr/bin/ruby
# encoding: UTF-8

# loreq.rb

load 'lo-0.rb'

puts "sono nel main: #{__FILE__}"

require './req.rb'
puts "v = #{$v}"

load 'lo-1.rb'
puts "v2 = #{$v2}"

ci servono 3 file, 2 per load e 1 per require, eccoli:

#!/usr/bin/ruby
# encoding: UTF-8

# lo-0.rb

puts "sono nel file: #{__FILE__}"
#!/usr/bin/ruby
# encoding: UTF-8

# rec.rb

$v = 8
#!/usr/bin/ruby
# encoding: UTF-8

# lo-1.rb

$v2 = 42

Inoltre nella variabile di sistema __FILE__ viene memorizzato il nome del file corrente. Altre cose sulle directories verranno raccontate in seguito, per adesso vediamo cosa succede se lo eseguiamo:

loreq

Tutto come previsto, anche le variabili definite nei file secondari sono visibili in quello principale. Sappiamo già che quelle il cui nome inizia con $ sono globali, vero?

Ma se questo è logico per require con load la variabile dev’essere globale? Uh… ehmm, io penso che …, dai proviamo (testload.rb e incload.rb):

#!/usr/bin/ruby
# encoding: UTF-8

# testload.rb

load 'incload.rb'
puts "nel main: prova = #{prova}"
# incload.rb

prova = 42
puts "nel file incluso: prova = #{prova}"

testload

OPS! no! load non si comporta come dovrebbe; la variabile dichiarata al suo interno non viene vista nel main. Quindi, se non è un bug che verrà corretto, non usare load ma require.

Accedere a file e directory

Non sempre i file e le risorse che ci servono sono nella stessa directory (cartella). Nessun problema, Ruby è in grado di gestire benissimo la cosa (quasi), ecco un primo esempio (path.rb):

#!/usr/bin/ruby
# encoding: UTF-8

# path.rb

nomefile = __FILE__
puts "nomefile = #{nomefile}"
pathname = File.expand_path(nomefile)
puts "pathname = #{pathname}"
dirname = File.expand_path('../', pathname)
puts "dirname = #{dirname}"
t = dirname + '/'
puts "inutile ma dirname + '/' = #{t}"
home = File.expand_path('~')
puts "home = #{home}"

path

Tutto come previsto, il modulo File fa parte di quelli predefiniti, immediatamente disponibili, senza usare require.

L’operatore + concatena le stringhe, come già visto. Per trattare i pathnames in realtà non serve ma volendo c’è. Ovviamente ~ è definita solo per Linux. Per Windows si può usare ENV, un hash che mappa le variabili di ambiente (environment), così (hvs.rb):

#!/usr/bin/ruby
# encoding: UTF-8

# hvs.rb

home = ENV['HOME']
puts "home = #{home}"

hvs

Attenzione: è un hash, le parentesi sono quadre 😉

FileUtils

Ci sono ancora tante cose da vedere; per esempio c’è tutto il modulo FileUtils. Che (almeno da me) non è che funzioni proprio come dovrebbe. Eccone un assaggio, maggiori informazioni, forse, in futuro (fu-pwd.rb):

#!/usr/bin/ruby
# encoding: UTF-8

# fu-pwd.rb

require 'fileutils.rb'

fdir = FileUtils.pwd
puts "directory corrente = #{fdir}"

questo = File.join(fdir, __FILE__)
puts "questo = #{questo}"

f = File.file?(questo)
d = File.directory?(questo)

print f, " ", d, "\n"

fu-pwd

Notare che il modulo dev’essere inserito con require (riga 6) e che il nome del file è tutto minuscolo. Le funzioni contenute sono elencate qui.

Non tutte funzionano, anche perché il modulo si riferisce a una versione diversa da quella che sto utilizzando. resta indispensabile il modulo File.

Notare alla riga 11 il modo sicuro per concatenare i path e i predicati file? e directory? (righe 14 e 15). Ne esistono parecchi altri, tra i quali exists?

Per oggi basta 😀 e per un po’ basta Ruby, ci sono altre cose in coda 😉

Annunci
Post a comment or leave a trackback: Trackback URL.

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione / Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione / Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione / Modifica )

Google+ photo

Stai commentando usando il tuo account Google+. Chiudi sessione / Modifica )

Connessione a %s...

%d blogger hanno fatto clic su Mi Piace per questo: