Matthew Mellott
Matthew Mellott

Reputation: 176

Breaking reopened class

In the example below I am reopening the Module class and setting instance variables. Can this possibly "break" the class if it already uses those instance variables for something else and how can this be avoided?

class Module
  def fields
    @fields ||= []
  end

  def foo name
    fields << name
  end
end

So far I haven't run into any issues with something similar to the above. However my next example shows how this could be a problem.

class Foo
  def bar
    @test = 1   
  end

  def print
    puts @test  
  end
end

class Foo
  def oops
    @test = 2   
  end
end

obj = Foo.new

obj.bar
obj.print #=> 1

# method that we added later sets instance variable
obj.oops #=> 2
obj.print

This worries me.

Upvotes: 0

Views: 42

Answers (2)

7stud
7stud

Reputation: 48649

Can this possibly "break" the class if it already uses those instance variables for something else and how can this be avoided?

1.9.3-p545 :003 > Module.new.instance_variables
 => [] 


1.9.3-p545 :004 > Module.new.instance_variable_defined? "@fields" => false 

Upvotes: 1

Zhomart
Zhomart

Reputation: 742

Here is an example what will it change and what won't

module Helper
  @fields = '@fields defined in Helper'

  def self.print_helper_fields
    p @fields
  end

  def print
    p @fields
  end
end

class A
  include Helper

  attr_accessor :fields
end

class Module
  def foo
    @fields = '@fields changed in Module#foo'
  end
end

a = A.new
a.fields = [1, 2, 3]

a.print # => [1, 2, 3]
Helper.print_helper_fields # => '@fields defined in Helper'

Helper.foo

a.print # => [1, 2, 3]
Helper.print_helper_fields # => '@fields changed in Module#foo'

Upvotes: 0

Related Questions