Reputation: 11101
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]
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
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
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
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
Reputation: 81510
There's two main performance penalties:
require
itself. In Ruby 1.9.1 and Ruby 1.9.2, the time taken to do all the require
s had worse than linear scalability - if you doubled the number of require
s, it took you more than twice as long - I think it took you four times as long.require
d. 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