(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5LHNRP9'); thecodest, Autor en The Codest - Página 13 de 13

Soluciones básicas

Supongamos que estamos utilizando la clase Foo que tiene un método público y un método privado:

clase Foo
  def barra
    :impresionante
  end

  privado

  def baz
    :algo_privado
  end
end

Todo es estupendo, vemos una solución de este tipo en prácticamente todos los proyecto. Ejecutar Foo.new.baz provocará el error NoMethodError (método privado 'baz' llamado para # ) y eso es lo que queríamos hacer. ¿Qué pasa si intentamos cambiar el formato de guardado y añadimos private como prefijo en la definición de la clase?

clase Foo
  def barra
    :impresionante
  end

  private def baz
    :algo_privado
  end
end

Como se puede ver después de ejecutar el código¡funciona de verdad! ¿Por qué podemos introducir la visibilidad del método antes de hacerlo? Porque al definir un método, def devuelve el nombre del método como un símbolo. Esta expresión no es sólo una parte de la sintaxis, sino de facto un método derivado de la clase Módulo y que trata este símbolo como un argumento. Para más información, consulte la documentación en este enlace. Ya que empezó tan fácil con private, vamos a intentar cambiar la visibilidad del método private.

clase Foo
  def barra
    :impresionante
  end

  private def baz
    :algo_privado
  end

  público :baz
end

¿Qué ocurrirá después de ejecutar el código?

irb(main):012:0> Foo.new.baz
=> :algo_privado

¡Éxito! Nuestro método de bases se hizo público porque lo hicimos visible dos veces. Por supuesto, la misma operación se aplica a los módulos.

Genial, pero ¿de dónde saca us?

Esta funcionalidad nos aporta mucho porque podemos cambiar libremente la visibilidad de un método al definirlo, o incluso cambiar la visibilidad de los métodos al heredarlos.

Ahora, echemos un vistazo a lo que Ruby 2.7 puede hacer en términos de cambiar la visibilidad de alias y accessors.

clase Foo
  private attr_accessor :impresionante_variable
fin

Desafortunadamente, obtenemos un error ya que el método privado espera symbols y attr_accessor. El código devuelve nil y por lo tanto este método no es compatible con el uso de private en Ruby 2.7. Entonces, ¿cuáles son nuestras opciones?

  1. Podemos utilizar attr_accessor bajo la palabra clave private para que funcione, es decir, obtendremos un error cuando queramos hacer referencia a la variable asombrosa_variableasombrosa_variable método.
clase Foo
  privado

  attr_accessor :impresionante_variable
fin
  1. La segunda opción es ejecutar el método privado en métodos generados por atributo_attr; en este caso, también tenemos que acordarnos de introducir allí el setter.
clase Foo
  attr_accessor :variable_asombrosa

  private :awesome_variable, :awesome_variable=
end

Problemas con el attr_ * no son los únicos obstáculos. Podemos encontrarnos con la misma dificultad cuando queremos crear un alias privado.

clase Foo
  private alias :barra, :barra_impresionante
fin

Ruby 3.0 y nuestro negocio

Afortunadamente, Ruby 3.0 introduce un gran cambio ya que los métodos de visibilidad pueden tomar array como argumento y los métodos alias, attr_ *, pueden reajustar el array con los nombres de los métodos que se han definido. Puedes leer más aquí.

Ahora, veamos algunos ejemplos en el último euba y comprobemos si realmente se han realizado los cambios y cómo podemos utilizarlos.

En el primer ejemplo, vamos a utilizar private antes del accessor attr:

clase Foo
  private attr_accessor :impresionante_variable
fin

Tal llamada no causará errores en el análisis sintáctico de la sintaxis y, lo que es importante, el variable_asombrosa yawesome_variable =se convierten en privados.

El método alias hará lo mismo ya que ahora también devuelve un símbolo como nombre del nuevo método y lo hace visible.

clase Foo
  private alias :barra, :barra_impresionante
fin

Un hecho interesante es que también podemos profundizar en otros métodos, por ejemplo, el impresionanteel módulo print puede ser llamado entre private y attres importante que dicho método devuelva una matriz con los nombres de los métodos que se encuentran en el lado derecho de la expresión.

clase Módulo
  def impresionante_imprimir(nombres)
    puts nombres
    nombres
  end
end
clase Foo
  private awesome_print attr_reader :awesome_bar
end 

Resumen

Espero que este artículo le resulte útil. En caso de más noticias sobre Ruby 3.0. leer más aquí.

¡Feliz codificación!

Oferta de desarrollador Ruby

Más información:

Cállate y llévate tu dinero #1: Costes ocultos y agilidad real en el proceso de desarrollo de productos

CTO retos - ampliación y crecimiento de productos de software

es_ESSpanish