Reputation: 3685
I am trying to access instance variables I have defined in RSpec in the modules that I am mixing into RSpec, but I can't seem to get this to work.
A simplifed spec file shows the problem I am having:
my_spec.rb
require 'rspec'
describe 'passing instance variables from specs into ruby mixins' do
it 'should pass the instance variable to the module' do
@a = 'a'
A.a.should == 'a'
end
it 'should pass the instance variable to the module in the module' do
@b = 'b'
A.b.should == 'b'
end
it 'should pass instance varisables from one module to the other' do
A.c.should == 'c'
end
end
module B
def b
return @b
end
def c
return @c
end
end
module A
extend B
@c = 'c'
def self.a
return @a
end
end
Results:
1) passing instance variables from specs into ruby mixins should pass the instance variable to the module
Failure/Error: A.a.should == 'a'
expected: "a"
got: nil (using ==)
# ./spec/my_spec.rb:6:in `block (2 levels) in <top (required)>'
2) passing instance variables from specs into ruby mixins should pass the instance variable to the module in the module
Failure/Error: A.b.should == 'b'
expected: "b"
got: nil (using ==)
# ./spec/my_spec.rb:11:in `block (2 levels) in <top (required)>'
Basically, I want to be able to access the instance variables @a, @b in both the modules A and B. I have tried using class variables @@a and @@b, but this doesn't work.
I can use global variables ($a and $b), and this works, but I feel this isn't elegant as they're global variables, which are evil.
Working code:
require 'rspec'
describe 'passing instance variables from specs into ruby mixins' do
it 'should pass the instance variable to the module' do
$a = 'a'
A.a.should == 'a'
end
it 'should pass the instance variable to the module in the module' do
$b = 'b'
A.b.should == 'b'
end
it 'should pass instance varisables from one module to the other' do
A.c.should == 'c'
end
end
module B
def b
return $b
end
def c
return @c
end
end
module A
extend B
@c = 'c'
def self.a
return $a
end
end
Any ideas?
Upvotes: 0
Views: 1093
Reputation: 2193
Even though they share the same name, they are scoped separately, because they are scoped to the instance where they are defined.
That is to say, the instance variables you've set in the specs only exist within the scope of those specs. Similarly, the instance variables inside the modules are similarly scoped to that context.
I'm not sure if it matches what you're trying to accomplish given the example is abstracted, but try this:
require 'rspec'
module B
def b= b
@b = b
end
def b
return @b
end
def c= c
@c = c
end
def c
return @c
end
end
module A
extend B
@c = 'c'
def self.a= a
@a = a
end
def self.a
return @a
end
end
describe 'passing instance variables from specs into ruby mixins' do
it 'should pass the instance variable to the module' do
A.a = 'a'
A.a.should == 'a'
end
it 'should pass the instance variable to the module in the module' do
A.b = 'b'
A.b.should == 'b'
end
it 'should pass instance varisables from one module to the other' do
A.c.should == 'c'
end
end
This could then be simplified to use attr_accessor
instead of defining the getter/setter methods manually.
The problem is that you're then simply testing the guts of Ruby.
Did I misunderstand the problem you're trying to solve?
Upvotes: 1