Reputation: 829
I have a directory full of ruby scripts for common tasks, and I've started to accumulate a set of common variables and methods that I find myself defining in each new script. The next step in improving this would seem to be creating a file (say, commonstuff.rb) and "require"ing that file from the other scripts so that the common variables and methods are all available everywhere and defined only once.
A simple attempt that didn't work:
commonstuff.rb
username=ENV['USER']
home_dir_path=ENV['HOME']
def print_and_execute(command, &block)
puts command
process_io = IO.popen(command + "2>&1")
while(line=process_io.gets)
if (block != nil)
yield line
else
puts line
STDOUT.flush
end
end
end
script1.rb
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/common_stuff'
puts home_dir_path # Fail
print_and_execute "date" # Fail
I've used ruby libraries and frameworks, but I don't have any of that available in my current environment. I just have straight ruby, and I'm a little rusty on some of the basic idioms that would work well here, or that would look right to a ruby expert.
Any help appreciated!
Upvotes: 2
Views: 2759
Reputation: 1294
There's a simpler solution. A module is not needed. I noticed you may have a mismatch in file name: You said you named your common file 'commonstuff.rb', but you require it with an underscore as 'common_stuff':
require File.dirname(__FILE__) + '/common_stuff'
Fix that with:
require_relative 'commonstuff' # require_relative if ruby >= 1.9
Your method should now work and we just need to make your variables accessible. Methods, globals, and constants are all imported into your namespace when you require a file, so simply change your variables to CONSTANTS (as another user suggested):
USERNAME = ENV['USER']
HOME_DIR_PATH = ENV['HOME']
or make them $globals:
$username = ENV['USER']
$home_dir_path = ENV['HOME']
You might want to use $global variables over CONSTANTS if you will redefine the variables while running. You can redefine constants, but ruby will generate a warning as it's not considered good practice.
Upvotes: 0
Reputation: 2947
You can call your methods through the module, or you can include the module in your namespace and call them directly (Sarah has code for all of this)
Upvotes: 1
Reputation: 31630
Wrap your methods and variables in a module, e.g.
module CommonStuff
USERNAME=ENV['USER']
HOME_DIR_PATH=ENV['HOME']
def print_and_execute(command, &block)
...
end
end
Then script1.rb might be like:
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/commonstuff.rb'
include CommonStuff
puts HOME_DIR_PATH # Win
print_and_execute "date" # Win
Or, if you don't want to include the module in your namespace:
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/commonstuff.rb'
puts CommonStuff::HOME_DIR_PATH # Win
CommonStuff.print_and_execute "date" # Win
See also Modules and the Programming Ruby page on modules.
Upvotes: 8