Charlie
Charlie

Reputation: 829

Ruby: share common variables and methods across a set of scripts

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

Answers (3)

liquidki
liquidki

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

Michael Sofaer
Michael Sofaer

Reputation: 2947

  1. Use capital letters for your constants (HOME_DIR_PATH, not home_dir_path)
  2. Put your methods inside a module.

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

Sarah Vessels
Sarah Vessels

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

Related Questions