我正在研究我的小新手项目。项目包括两个脚本。脚本编号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!
答案 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
使用全局变量并不是最好的方法。因此,除非这是一次性的,否则最好重新构建代码。