Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

268
Views
¿Cómo las diferentes formas de definir una clase influyen en la forma en que funciona include?

Tengo un módulo simple que define una constante y la hace privada:

 module Foo Bar = "Bar" private_constant :Bar end

Puedo incluirlo en una clase como esta, y funciona como se esperaba:

 class User include Foo def self.test Bar end end puts User.test # => Bar begin User::Bar rescue => exception puts "#{exception} as expected" # => private constant Foo::Bar referenced as expected end

(Llamémoslo definición de "clase típica")

Luego probé el enfoque Class.new , pero falló miserablemente:

 X = Class.new do include Foo def self.test Bar # Line 28 pointed in the stack trace end end begin X::Bar rescue => exception puts "#{exception}" # => private constant Foo::Bar end puts X.test # test.rb:28:in `test': uninitialized constant Bar (NameError) # from test.rb:28:in `<main>'

¿Por qué? Siempre pensé que class Something y Something = Class.new son equivalentes. ¿Cuál es la diferencia real?

Luego tuve un golpe de inspiración y recordé que hay una forma alternativa de definir los métodos de clase, que realmente funcionó:

 X = Class.new do class << self include Foo def test Bar end end end begin X::Bar rescue => exception puts "#{exception}" # => uninitialized constant X::Bar end puts X.test # Bar

Nuevamente, ¿por qué funciona este y por qué la excepción ahora es diferente: private constant Foo::Bar frente a la uninitialized constant X::Bar ?

Parece que esas 3 formas de inicializar clases difieren de una manera matizada.

  1. hace exactamente lo que quiero: la barra es accesible internamente, y acceder a ella da una excepción sobre la referencia a la constante privada.
  2. el segundo da la excepción "ok", pero no tiene acceso a Bar en sí
  3. tercero tiene acceso, pero ahora da una excepción ligeramente diferente

¿Qué está pasando exactamente aquí?

over 4 years ago · Santiago Trujillo
1 answers
Answer question

0

Esta es una de las mayores trampas en Ruby: el alcance de la definición constante es parcialmente sintáctico , es decir, depende de cómo esté estructurado el código que lo rodea.

 module Foo Bar = "Bar" end

Bar está dentro de una definición de module , por lo que se define en ese módulo.

 class << self include Foo end

Bar se incluye dentro de una definición de class , por lo que se define en esa clase.

 Class.new do include Foo end

No hay una class o module adjunto (esta es una llamada de método normal con un bloque), por lo que la constante se define en el nivel superior.

En cuanto a su tercer error, creo que se debe a que la constante se definió en la clase singleton (eso es lo que es la class << self ) frente a la clase misma. Son dos objetos de clase separados.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!