如何将两个ruby脚本放入一个工作程序中?

时间:2012-11-13 11:19:00

标签: ruby command-line-interface

我正在研究我的小新手项目。项目包括两个脚本。脚本编号1是命令行界面,用于从用户返回参数。脚本编号2创建笛卡尔积并将其写入文本文件。我的想法是让所有东西都工作,而不会把evertything放到一个文件中)。当我尝试使用'load'时,我收到此错误:“

Carthese_product.rb:3:in `<top (required)>': undefined local variable or method
`x_min' for main:Object (NameError)
        from D:/Cli_file.rb:25:in `load'
        from D:/Cli_file.rb:25:in `<main>'

Script1(Cli_file.rb):

  require 'trollop'
  opts = Trollop::options do
  banner <<-EOS
Welcome to points generator!

Usage:
       test [options] <filenames>+
where [options] are:
EOS
    opt :x_min,             "Minimal value of X", :type => :int  
    opt :x_max,             "Maximal value of X", :type => :int 
    opt :y_min,            "Minimalna wartosc Y", :type => :int 
    opt :y_max,             "Maksymalna wartosc Y", :type => :int 
    opt :interval,          "Interval between points", :type => :int, :default => 1 
    opt :products_file,     "Name of products_file", :type => :string, :default =>    
                            "Products"     
  end

a= opts
x_min = a[:x_min]
x_max = a[:x_max]
y_min = a[:y_min] 
y_max = a[:y_max]
interval = a[:interval]
products_file = a[:products_file]
load 'Carthese_product.rb'

Script2(Carthese_product.rb)

products = []

(x_min/interval..x_max/interval).each do |x|
(y_min/interval..y_max/interval).each do|y|
products << [x*interval,y*interval]
end
end
a = products.map.with_index{|w, i| "#{i+1} #{w[0].to_s} #{w[1].to_s} \n"}

aFile = File.new( products_file, "w+")
if aFile
    a.each{|x| aFile.write(x)}
else
puts "Something wrong!"
end

我知道最容易解决的问题是将所有内容都放在一个脚本中,但出于教育目的,我想找到另一种方法!感谢您的帮助&amp; intrest!

2 个答案:

答案 0 :(得分:2)

您正在尝试使用局部变量将数据从一个脚本传递到另一个脚本。它不起作用,因为局部变量在顶层定义时具有文件范围,因此无法从单独的文件中访问。

您必须为代码创建适当的接口,以便可以从其他脚本引用它。创建一个实现笛卡尔积的模块:

# cartesian.rb

module Cartesian
  extend self

  def product(x_range, y_range, interval = 1)
    [].tap do |products|
      x_range.step interval do |x|
        y_range.step interval do |y|
          products << [x, y]
        end
      end
    end
  end
end

现在,require命令行应用程序可执行文件中的此文件,使用命令行中给出的数据并编写输出:

#/usr/bin/env ruby
require 'cartesian'

# Option parsing

Cartesian.product(x_min..x_max, y_min..y_max, interval).each do |product|
  puts "(#{product.first}, #{product.last})"
end

我建议将程序的输出打印到标准输出流。这样,如果您愿意,可以轻松地将输出重定向到文件:

./cartesian-product $ARGUMENTS > product.list

答案 1 :(得分:0)

局部变量不会从一个文件传播到另一个文件。为此,您必须通过前缀$使它们成为全局变量。然后,您可以通过运行Cli_file.rb来运行两个脚本。

您的脚本现在变为:

Cli_file.rb

require 'trollop'
opts = Trollop::options do
banner <<-EOS
Welcome to points generator!

Usage:
   test [options] <filenames>+
where [options] are:
EOS
   opt :x_min,             "Minimal value of X", :type => :int  
   opt :x_max,             "Maximal value of X", :type => :int 
   opt :y_min,            "Minimalna wartosc Y", :type => :int 
   opt :y_max,             "Maksymalna wartosc Y", :type => :int 
   opt :interval,          "Interval between points", :type => :int, :default => 1 
   opt :products_file,     "Name of products_file", :type => :string, :default =>    
                        "Products"     
end

a= opts
$x_min = a[:x_min]
$x_max = a[:x_max]
$y_min = a[:y_min] 
$y_max = a[:y_max]
$interval = a[:interval]
$products_file = a[:products_file]
load 'Carthese_product.rb'

Carthese_product.rb

products = []

($x_min/$interval..$x_max/$interval).each do |x|
($y_min/$interval..$y_max/$interval).each do|y|
products << [x*$interval,y*$interval]
end
end
a = products.map.with_index{|w, i| "#{i+1} #{w[0].to_s} #{w[1].to_s} \n"}

aFile = File.new( $products_file, "w+")
if aFile
    a.each{|x| aFile.write(x)}
else
    puts "Something wrong!"
end

使用全局变量并不是最好的方法。因此,除非这是一次性的,否则最好重新构建代码。