Radek
Radek

Reputation: 11101

Do not necessary require(s) matter?

I want to be able to have one ruby file that can require all the common dependencies, so that other files can just have one require on this shared file.for example; I have foo.rb and bar.rb and allrequires.rb. I want to have the line require "allrequires.rb" in both foo.rb and bar.rb, but bar.rb doesn't need all the requires.

Does it matter if I use require in .rb file that do not really require that file? Could it have an impact on performance maybe?

I am currently on ruby 1.8.7 (2010-08-16 patchlevel 302) [i386-mingw32]

Update

It looks like it is not the best idea to 'share'/use all requires in both .rb files. What would be solution to that?

Right now I can think of using file name in a condition.

Upvotes: 3

Views: 138

Answers (4)

Radek
Radek

Reputation: 11101

My final solution is (in case someone finds it useful):

requires.rb is called from web.rb or testweb.rb, rufus.rb or testrufus.rb

called_from=caller[0].split(":")[0]


puts "loading web 'requires' for file: #{called_from} ..." if (["web"].any?{|s| called_from[s]})
puts "loading web 'requires' for file: #{called_from} ..." if (["rufus"].any?{|s| called_from[s]})
puts "loading web 'requires' for file: #{called_from} ..." if (["settings"].any?{|s| called_from[s]})

require 'rubygems'

require 'socket'        if (["web","settings"].any?{|s| called_from[s]})
require 'ruby-growl'    if (["web","settings","rufus"].any?{|s| called_from[s]})
require 'sinatra'       if (["web"].any?{|s| called_from[s]}) 

Thank you @Andrew for the explanation and @peter for the hint how to solve this.

Upvotes: 0

peter
peter

Reputation: 42192

Another approach of conditional requiring, the following script gives no error on the JSON parser because it is named require1.rb, in scripts that have no name like require1.rb of script2.rb the gem isn't required

require 'json' if "require1.rb, script2.rb"[File.basename(__FILE__)]

p File.basename(__FILE__)

text = '[{ "name" : "car", "status": "good"}, { "name" : "bus", "status": "bad"},{ "name" : "taxi", "status": "soso"},
  {"noname":"", "status" : "worse"}
]' 
data = JSON.parse(text) 

p data.collect { |item| item['name'] } 

EDIT: here a version that uses an array

["require1.rb","script1.rb"].find{|script|require 'json' if script===File.basename(__FILE__)}

Upvotes: 1

peter
peter

Reputation: 42192

Yes, there will be a speedpanalty, you can benchmark how mutch to consider if it realy matters. With multiple require's i put hem in my code like this so that it doens't take much screenspace.

['green_shoes','Hpricot'].each(&method(:require))

You could also do a conditional require, but that would be ugly having all around your code

begin
  data = JSON.parse(text)
rescue
  require 'json_pure' 
  data = JSON.parse(text)
end

So in short, give each rb its own require's

Upvotes: 0

Andrew Grimm
Andrew Grimm

Reputation: 81510

There's two main performance penalties:

  1. The time taken to do the require itself. In Ruby 1.9.1 and Ruby 1.9.2, the time taken to do all the requires had worse than linear scalability - if you doubled the number of requires, it took you more than twice as long - I think it took you four times as long.
  2. The time taken to execute the code in the file being required. If you have code like the following, then executing the code will take a non-trivial amount of time.
class MyClass
  MY_CONSTANT = File.read("data.txt")
end

Upvotes: 3

Related Questions