Subsecciones


Ruby

Lenguaje dinámico, de propósito general, creado a mediados de los 90 por Yukihiro "Matz" Matsumoto

Ejemplo sencillo:

#!/usr/bin/ruby
=begin
Abre y lee un fichero
Se usa un bloque (entre do - end)
El identado no es necesario
El fichero se cierra
automáticamente al acabar el bloque.
=end
File.open("/etc/passwd", "r") do |f1|
  while linea = f1.gets
    puts linea
  end
end    # Fin del bloque

Tipos de datos en Ruby

  1. Arrays
    frutas=[ "naranjas", "uvas", 123, "limones", "uvas" ]
    frutas<<"peras"     # Añade un string
    frutas.delete(123)
    frutas.uniq!        # Elimina elementos duplicados
    frutas.insert(2, %w{fresas pomelos}) # Inserta otro array 
                                         # %w -> array de strings 
                                         # sin usar comillas
    puts frutas # naranjas,uvas,fresas,pomelos,limones,peras
    puts frutas.length  # 5
    puts frutas[2][1]   # pomelos
    frutas.delete_at(2)
    frutas.insert(3, "cerezas", "kiwis")  # Inserta 
    frutas.sort! # Ordena ``in-place''
    puts frutas  # cerezas, kiwis, limones, naranjas, peras, uvas
    

  2. Rangos
    nums = -1..9
    puts nums.include?(10) # false (10 no en el rango)
    puts nums === 0        # true (0 en el rango)
    puts nums.first        # -1
    puts nums.last         # 9
    puts nums.to_a         # [-1,0,1,2,3,4,5,6,7,8,9]
    puts nums.to_s         # "-1..9"
    array = nums.reject {|i| i < 7}
    puts array             # [7, 8, 9]
    

  3. Arrays asociativos
    edad_de = {'Eva'=>23, 'Ana'=>19, 'Oscar'=>41}
    puts edad_de['Ana']     # Imprime 19
    edad_de['Eva'] = 18     # Cambia un valor
    edad_de['Juan'] = 26    # Añade un elemento
    edad_de.delete('Oscar') # Borra un elemento
    

Control de flujo

Lazos

frutas=["naranjas", "uvas"]

# Bloque usando do-end
frutas.each do |f|
  puts "#{f}:#{f.length}"  # naranjas:8 
end			   # uvas:4

print "Añade otra fruta: "
nf = gets.chomp    # Lee stdin y elimina el \n
while nf != ""     # Si la entrada no está vacía
  frutas<<nf.to_s  # añádela a la lista
  print "Añade otra fruta: "
  nf = gets.chomp
end

# Bloque usando llaves
3.times { |i| puts i }   # 0, 1, 2

Condicionales

print "Introduce un entero: "
x = gets.chomp.to_i
if x < 0
  x = 0  
  puts "Negativo cambiado a 0"
elsif x == 0
  puts "Cero"
else
  puts "Positivo"
end
# Forma unless
unless x == 0 
  puts x
end
# Case
scale = 8
case scale
  when    0: puts "lowest"
  when 1..3: puts "medium-low"
  when 4..5: puts "medium"
  when 6..7: puts "medium-high"
  when 8..9: puts "high"
  when   10: puts "highest"
  else       puts "off scale"
end

Funciones

# Argumento con valor por defecto
def compra(fr, nf="manzanas")
  fr<<nf
end
# Número de argumentos variable
def compram(fr, *nf)
  # Recorro todos los argumentos
  nf.each { |f| fr<<f }
end

frutas=[]
# Los paréntesis no son obligatorios
compra frutas, "peras"
# Usa el valor por defecto
compra(frutas)
# Usa múltiples argumentos
compram(frutas, "limones", "naranjas")
puts frutas   # peras, manzanas, limones, naranjas

Expresiones regulares

# Comprueba direcciones de e-mail
print "Introduce un e-mail: "
s = gets.chomp
if /\w+@\w+\.\w+((\.\w+)*)?/.match(s)
  puts "Dirección correcta"
end

# Busca URLs en un fichero de texto
# Abre el fichero de solo lectura
# comprobando excepciones
begin
  f = File.open("fich.txt","r")
rescue Exception => msg
  print "No puedo abrir --> ", msg, "\n"
  exit(1)
end
# Expresión regular a buscar (\s == [:space:])
urlreg = /http:\/\/([^\s]+)/
nl=1
f.each do |l|
  # Busca todas las URLs en la línea actual 
  # e imprimelas
  l.scan(urlreg) { |m| print "Línea #{nl}-><#{m}>\n" }
  nl+=1
end
f.close
# Corrige un string
s = "oCme más futra"
s.gsub!("oCme", "Come")
s.gsub!("futr", "frut")
puts s  # Imprime "Come más fruta"
# Separa un string en una lista
s = "Uno:Dos.Tres-Cuatro"
l=s.split(/[:.-]/)

Ejemplos

  1. En un directorio, renombra *.xml a *.html
    # Módulo con utilidades para ficheros
    require 'fileutils'
    # Comprueba argumentos
    if ARGV.length < 1
      puts "Necesito un directorio como argumento"
      exit
    end
    dir=ARGV[0]
    
    # Chequea que sea un directorio
    unless File.directory?(dir)
      puts dir+" no es un directorio"
      exit
    end
    
    # Recorre los ficheros .xml
    begin
      # Cambia al directorio
      FileUtils.cd(dir)
      Dir.glob("*.xml") do |f|
        # Construye el nuevo nombre  
        new = File.basename(f, ".xml")+".html"
        # Renombra los ficheros
        File.rename(f, new)
      end
    rescue Exception => msg
      puts "Error: "+msg
    end
    

  2. Muestra información sobre un proceso en ejecución
    print "Proceso a chequear: "
    proc = gets.chomp
    begin
      # Ejecuta el comando ps y obten la salida
      output = `ps -edf|grep #{proc}`
      # Separa la salida en campos
      procinfo = output.split()
      
      # Muestra los resultados
      puts "Ejecutable  : #{procinfo[7]}"
      puts "Propietario : #{procinfo[0]}"
      puts "PID         : #{procinfo[1]}"
      puts "PPID        : #{procinfo[2]}"
      puts "Hora inicio : #{procinfo[4]}"
    rescue Exception => msg
      puts "Error: "+msg
    end
    

  3. Busca recursivamente ficheros que cumplen un patrón
    # Módulo adicional
    require 'find'
    print "Directorio inicial: "
    searchpath = gets.chomp
    print "Patrón de búsqueda: "
    pattern = gets.chomp
    # Busca recursivamente
    Find.find(searchpath) do |path|
      # Comprueba si el patrón corresponde con el fichero
      if File.fnmatch(pattern, File.basename(path))
        # Muestra el nombre del fichero
        puts  "Fichero             : " +  File.basename(path)
        # Información sobre el fichero
        stat = File.stat(path)
        # Muestra los permisos en octal
        printf("Permisos            : %o\n", stat.mode)
    
        # Muestra el UID y el GID del propietario
        print "UID del propietario : "
        puts stat.uid
        print "GID del propietario : "
        puts stat.gid
        # Muestra el tamaño del fichero
        print "Tamaño (bytes)      : "
        puts stat.size
        puts "----------------------------------------"
      end
    end
    

Referencias

Administración de Sistemas e Redes <ASR.USC[at]gmail.com>
Tomás Fernández Pena <tf.pena[at]usc.es>
Última actualización: 30-09-15 17:44 por tomas

Creative Commons License
Curso de Administración de Sistemas y Redes por Tomás Fernández Pena se distribuye bajo la licencia Creative Commons Recoñecemento-Compartir baixo a mesma licenza. 3.0 España.
Trabajo original en persoal.citius.usc.es/tf.pena/ASR.