Circular Dependencies in Ruby

Circular Dependencies in Ruby

If you need to access a subclass from a superclass then there's a good chance that your model is broken (i.e. it should be one class).

That said, there are a couple of obvious solutions:

1) just create a file that requires the foo files:

all_foos.rb:

require "foo.rb"
require "foo_sub.rb"

and remove the requires from foo.rb and foo_sub.rb.

2) remove the require from foo.rb

3) remove the require from foo_sub.rb and put the require in foo.rb after the class definition.

Ruby isn't C++, it won't complain about FooSub.SOME_CONSTANT until you call Foo#foo() ;)

ruby: how to require correctly (to avoid circular dependencies)

After asking about this on the Ruby mailing list a while back, when I used to have a file in my libraries just for requiring things, I changed to these two rules:

  1. If a file needs code from another in the same library, I use require_relative in the file that needs the code.

  2. If a file needs code from a different library, I use require in the file that needs the code.

As far as I understand it, Ruby requires in the order it is asked to, and so it doesn't matter about circular dependencies.

(Ruby v1.9.2)

In answer to the comment about the example showing circular dependency problems:

actually, the problem with the example isn't that the requires are circular, but that B.calling is called before the requires have completed. If you remove the B.calling from b.rb it works fine. For example, in irb without B.calling in the code file but run afterwards:

$ irb

require '/Volumes/RubyProjects/Test/stackoverflow8057625/b.rb'

=> true

B.calling

doing..

=> nil

Can gems have circular dependencies?

Do not have circular runtime dependencies.

It should be OK, if weird, for one gem to have a development dependency on another gem which has a runtime dependency on the first.

Nevertheless, I would not recommend it. I would recommend ensuring that your dependencies graph is completely empty of cycles.

Rails nested circular dependencies

You don't have circular dependencies.

  • Location relies on nothing to be created
  • Bin relies on location
  • InventoryItem relies on bin and location

So if you create them in the right order

  1. Location
  2. Bin (attached to location)
  3. Inventory Item (attached to both)

you should be fine.

Something like this

# the nesting in params may be off but you can definitely figure this out by looking at the console log of form's request.

# 1. Create location with name (no dependencies)
location = Location.create({name: params[:location][:name]})

# 2. Create bin referencing location
bin = Bin.create({location: location, name: params[:bin][:name]})

# 3. Create inventory item referencing both.
@inventory_item = InventoryItem.create({bin: bin, location: location})

I'm not sure how to do this with accepts_nested_attributes_for but that would be a clean solution if you can get it working.

Circular dependency on Gemfile

Oh, sorry, I didn’t get this at the first glance.

casein gem references itself:

Puelos-Macbook:ChataBackend paulo$ gem dependency casein
Gem casein-5.0.0.0
authlogic (= 3.4.2)
!! NB⇒ casein (>= 0)
jquery-rails (>= 0)
scrypt (= 1.2.1)
will_paginate (= 3.0.5)

It was allowed for bundle prior to 1.9, but disallowed now. You have two options:

  1. downgrade bundler to 1.8 and re-run bundle install.
  2. clone the casein gem, patch casein.gemspec by removing self-reference and submit a pull-request. https://github.com/spoiledmilk/casein3/blob/master/casein.gemspec#L103

NB Actually this was already done by community, e.g. https://github.com/russellquinn/casein
So, you might simply require that version explicitly via gem 'casein', git: 'github.com:russellquinn/casein'.

Hope it helps.



Related Topics



Leave a reply



Submit