0

私は小さな初心者プロジェクトに取り組んでいます。プロジェクトは 2 つのスクリプトで構成されます。スクリプト番号 1 は、ユーザーからパラメーターを受け取るコマンド ライン インターフェイスです。スクリプト番号 2 はデカルト積を作成し、テキスト ファイルに書き込みます。私の考えは、すべてを 1 つのファイルに入れることなく、すべてを機能させることです)。「ロード」を使用しようとすると、次のエラーが表示されます:"

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

すべてを 1 つのスクリプトにまとめることが最も簡単な解決策であることはわかっていますが、教育目的で別の方法を見つけたいと考えています。助けてくれてありがとう!

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

ただし、グローバル変数を使用することは、最善の方法ではありません。したがって、これが 1 回限りでない限り、コードを再構築する方がよいでしょう。

于 2012-11-13T14:04:21.050 に答える