0

我正在做我的小新手项目。项目由两个脚本组成。脚本编号 1 是命令行界面,用于接收用户的参数。脚本号 2 创建笛卡尔积并将其写入文本文件。我的想法是在不将所有内容放入一个文件的情况下让一切正常工作)。当我尝试使用“加载”时,出现此错误:”

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>'

脚本 1(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

我知道最简单的解决方案是将所有内容放入一个脚本中,但出于我的教育目的,我想找到另一种方法!感谢您的帮助和兴趣!

4

2 回答 2

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
于 2012-11-13T13:57:23.820 回答
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

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

于 2012-11-13T14:04:21.050 回答