vamsiampolu vamsiampolu - 1 month ago 9
Ruby Question

Circular require issue with Ruby

I am trying to implement a currency based application using Ruby, I find that:

require 'dollar'
require 'franc'

puts 'Why does this not work?'

class Money

attr_reader :amount

def self.dollar(number)
Dollar.new number
end

def ==(other)
self.amount == other.amount
end

def self.franc(number)
Franc.new(number)
end

end


I have the
Franc
class that looks like this:

require 'money'

class Franc < Money

attr_reader :amount

def initialize(amount)
@amount = number
end

def times(mul)
amount = @amount * mul
Franc.new(amount)
end

def ==(other)
return false unless other.is_a? self.class
super
end

end


This is a direct translation of some of the code from the Kent Beck book to Ruby. When I run
bin/rspec
I see:

/home/vamsi/Do/wycash/lib/franc.rb:3:in `<top (required)>': uninitialized constant Money (NameError)
from /home/vamsi/Do/wycash/lib/money.rb:2:in `require'
from /home/vamsi/Do/wycash/lib/money.rb:2:in `<top (required)>'
from /home/vamsi/Do/wycash/lib/dollar.rb:1:in `require'
from /home/vamsi/Do/wycash/lib/dollar.rb:1:in `<top (required)>'
from /home/vamsi/Do/wycash/spec/dollar_spec.rb:1:in `require'
from /home/vamsi/Do/wycash/spec/dollar_spec.rb:1:in `<top (required)>'
from /home/vamsi/Do/wycash/.bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/configuration.rb:1435:in `load'
from /home/vamsi/Do/wycash/.bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/configuration.rb:1435:in `block in load_spec_files'
from /home/vamsi/Do/wycash/.bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/configuration.rb:1433:in `each'
from /home/vamsi/Do/wycash/.bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/configuration.rb:1433:in `load_spec_files'
from /home/vamsi/Do/wycash/.bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:100:in `setup'
from /home/vamsi/Do/wycash/.bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:86:in `run'
from /home/vamsi/Do/wycash/.bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:71:in `run'
from /home/vamsi/Do/wycash/.bundle/ruby/2.3.0/gems/rspec-core-3.5.4/lib/rspec/core/runner.rb:45:in `invoke'
from /home/vamsi/Do/wycash/.bundle/ruby/2.3.0/gems/rspec-core-3.5.4/exe/rspec:4:in `<top (required)>'
from bin/rspec:17:in `load'
from bin/rspec:17:in `<main>'

Answer

You should put require 'franc' after you defined Money in your first script.

The class Money will be then defined when Ruby executes your second_script.