6 nov. 2018

Teoría - Convenciones en Ruby

Convenciones en Ruby

 Documento sacado de:

Cuando te enfrentas por primera vez a código escrito en Ruby, probablemente te recuerde otros lenguajes que hayas usado. Esto es a propósito. La mayor parte de la sintaxis es familiar para los usuarios de Perl, Python, y Java (entre otros lenguajes), así que si has usado alguno de estos, aprender Ruby será muy fácil.

Este documento contiene dos secciones. La primera intenta ser un resumen de lo que puedes esperar ver al aprender Ruby viniendo de otro lenguaje. La segunda sección se enfoca en determinadas funcionalidades del lenguaje y cómo podrían compararse a lo que ya puedas estar familiarizado.

                   Qué esperar: Lenguaje X a Ruby

·      A Ruby desde Java
·       A Ruby desde PHP
Estamos en proceso de traducir todos estos artículos, pero mientras lo hacemos no queremos privarte de que los leas en inglés:
·       To Ruby From C and C++ (en inglés)
·       To Ruby From Java (en inglés)
·       To Ruby From Perl (en inglés)
·       To Ruby From PHP (en inglés)
·       To Ruby From Python (en inglés)

                   Funcionalidades importantes del lenguaje y algunas advertencias

Aquí tienes algunas referencias y consejos sobre funcionalidades de Ruby que verás mientras lo aprendes.

                        Iteración

Dos funcionalidades de Ruby que se diferencian de lo que puedes haber visto previamente, y que toma cierto tiempo acostumbrarse a ellas, son los “bloques” e iteradores. En vez de recorrer un índice (como con C, C++, o Java anterior al 1.5), o recorrer una lista (como el for (@a) {...} de Perl, o for i in aList: ... en Python, con Ruby verás muy frecuentemente código de este estilo:
una_lista.each do |este_item|
  # Estamos dentro del bloque.
  # Trabaja con este_item.
end
Para obtener más información sobre each (y sus amigos collectfind,injectsort, etc.), ejecuta ri Enumerable (y después ri Enumerable#nombre_del_metodo).

                        Todo tiene un valor

No hay diferencia entre una expresión y un comando. Todo tiene un valor, incluso si ese valor es nil. Esto es posible:
= 10
= 11
= if x < y
  true
else
  false
end
# => true

                        Los symbols (símbolos) no son strings especiales

A muchos novatos en Ruby les cuesta entender qué son los symbols, y qué utilidad pueden tener.
Los symbols pueden ser descritos como identidades. Lo importante de un Symbol es quién es, no qué es. Arranca irb y experimenta la diferencia:
irb(main):001:0> :jorge.object_id == :jorge.object_id
=> true
irb(main):002:0> "jorge".object_id =="jorge".object_id
=> false
irb(main):003:0>
El método object_id retorna la identidad de un objeto. Si dos objetos tienen el mismo object_id, son el mismo objeto (apuntan al mismo objeto en la memoria).
Como puedes ver, una vez que has usado un Symbol, cualquier otro Symbol con los mismos caracteres referencia al mismo objeto en memoria. Para dos symbols que representan los mismos caracteres, elobject_id es el mismo.
Ahora veamos el String (“jorge”). El object_id no es el mismo. Eso significa que representan a dos objetos diferentes en memoria. Siempre que uses un nuevo String, Ruby reserva memoria para él.
Si tienes dudas sobre usar un Symbol o un String, considera qué es más importante: la identidad de un objeto (por ejemplo la Key de un Hash), o el contenido (en nuestro ejemplo, “jorge”).

                        Todo es un objeto

Todo es un objeto” no es una exageración. Incluso las clases y los enteros son objetos, y puedes hacer con ellos las mismas cosas que con cualquier otro objeto:
# Esto es lo mismo que:
# class MiClase
#   attr_accessor :variable_de_instancia
# end
MiClase = Class.new do
  attr_accessor :variable_de_instancia
end

                        Constantes variables

Las constantes no son realmente… constantes. Si modificas una constante previamente inicializada, Ruby disparará una advertencia, pero no detendrá tu programa. De todas formas, eso no quiere decir que deberías redefinir tus constantes.

                        Convenciones de sintaxis

Ruby impone algunas convenciones de sintaxis. Si un identificador comienza con una letra mayúscula, es una constante. Si comienza con un símbolo de moneda ($), es una variable global. Si comienza con @, es una variable de instancia. Si comienza con @@, es una variable de clase.
Sin embargo, los nombres de los métodos tienen permitido comenzar con letras mayúsculas. Esto puede confundirte, como muestra el siguiente ejemplo:
Constante = 10
def Constante
  11
end
Ahora Constante vale 10, pero Constante() retorna 11.

                        Falsos parámetros nombrados

A diferencia de Python, Ruby no tiene parámetros nombrados. Sin embargo, pueden ser emulados mediante el uso de symbols y hashes. Ruby on Rails, entre otros, usa esto a discreción. Por ejemplo:
def parametros_con_nombre( params )
  params
end
parametros_con_nombre( :param_uno => 10, :param_dos =>42 )
# => {:param_uno=>10, :param_dos=>42}

                        La verdad universal

En Ruby, todo excepto nil y false es considerado true. En C, Python y muchos otros lenguajes, 0* y posiblemente otros valores, como listas vacías, son considerados *false. Examina el siguiente código Python (el ejemplo aplica también a otros lenguajes):
# en Python
if 0:
  print "0 es verdadero"
else:
  print "0 es falso"
Esto imprimirá “0 es falso”. El equivalente en Ruby:
# en Ruby
if 0
  puts "0 es verdadero"
else
  puts "0 es falso"
end
Imprime “0 es verdadero”.

                        Los modificadores de acceso aplican hasta el fin del alcance

En el siguiente código Ruby,
class MiClase
  private
  def un_metodo; true; end
  def otro_metodo; false; end
end
Puede ser que esperes que otro_metodo sea de alcance público. Esto no es así. El modificador de acceso ‘private’ continúa hasta el fin del alcance, o hasta que aparezca un nuevo modificador de acceso, lo que ocurra primero. Por defecto, los métodos son públicos:
class MiClase
  # Ahora un_metodo es público
  def un_metodo; true; end
  private
  # otro_metodo es privado
  def otro_metodo; false; end
end
publicprivate y protected en realidad son métodos, así que pueden recibir parámetros. Si pasas un símbolo a uno de ellos, la visibilidad de ese método es alterada.

                        Acceso a los métodos

En Java, public significa que un método puede ser accedido por cualquiera. protected significa que las instancias de la clase, instancias de sus descendientes así como también de clases en el mismo paquete, pueden accederlo, pero nadie más. Y private significa que los métodos son accesibles únicamente desde las instancias de la clase.
En Ruby esto es un poco diferente. public es, naturalmente, público.private significa que los métodos son accesibles sólo cuando pueden ser invocados sin un receptor explícito. Sólo self tiene permitido ser el receptor de la invocación a un método privado.
Al que debemos estar atentos es a protected. Un método protegido puede ser llamado desde una instancia de una clase o las instancias de sus ancestros, pero también con otra instancia como su receptor.
Ejemplo, adaptado del Ruby FAQ:
$ irb
irb(main):001:0> class Test
irb(main):002:1>   # public por defecto
irb(main):003:1*   def func
irb(main):004:2>     99
irb(main):005:2>   end
irb(main):006:1>
irb(main):007:1*   def ==(otro)
irb(main):008:2>     func == otro.func
irb(main):009:2>   end
irb(main):010:1> end
=> nil
irb(main):011:0>
irb(main):012:0* t1 = Test.new
=> #<0x34ab50>
>   
> <0x342784>
>   
> 
> 
 
  
>   
> 
> 
>   
> 
> 
  
>   
> 
> 
>   
  <0x342784>
        
         
         
>

                        

    
 
   
       
  
   
  
     >

                        

        
   

                        

 
   
    
  
  
 >
 
  
 >
  
 >

                        

  
    
       
        
   
>

                        

  
  
  

                        

   
  & 
  
   
         
  > 
 
 
>

                        

 
 
  
     
      
  
 
      
  
&&