2011-09-17 23 views
0

ファイルを行の配列に読み込み、その行を解析して構造化データを取得するコードがあります。入力ファイルにはさまざまな異なるデータ型があり、異なる処理が必要です。さらに、さまざまなアカウント(携帯電話番号)の主要セクションがあります。なぜ/変数はゼロに設定されていますか

私はアカウント行を探している行をループし、そのアカウントを特定してから、次のアカウント行が見つかるまでそのアカウントを使用したいと考えています。その間の線は、そのアカウントに属するさまざまなタイプのデータを表す可能性があります。問題は、私がアカウントの行を見つけてローカル変数(cur_num)を設定した後、変数を使用したいときに変数をnilに設定することです。なぜ、どうしたのですか?私はRubyを学んでいるので、これ以上の修正が必要です。なぜこのように動作するのか理解したいのですが。ここで

は私のコードです:

count = 0 
    cur_num = "" 
    lines.each do |line| 
    unless (line.strip.eql?("")) # edited due to comment from normalocity 
    if (line.slice(0,15) == "Mobile Number:,") 
     cur_num = line.slice(15,12) 
     count = 1 
     puts "Current Number: #{cur_num}" 
     #puts "Object Type: #{cur_num.class}" 
    else 
     data = line.strip.split(',') 
     if (data.length > 8) 
     data.unshift(cur_num) 
     #if (count.modulo(10) == 0 || count == 1) 
      puts "[#{cur_num}] #{data.inspect}" 
      #pp data 
     #end 
     count += 1 
     end 
    end 
    end 
end 

入力データ構造の概要は、次のようになります。

Account 1 
    Data Section A 
     data line 1 
     data line 2 
    Data Section B 
     data line 1 
     data line 2 
Account 2 
    Data Section A 
     data line 1 
     data line 2 
    Data Section B 
     data line 1 
     data line 2 

end 

は、行の配列を複製するコードを追加します場合は、この上記のコードサンプルを貼り付けなければなりません複製しようとしています。私は私の質問を読みやすくしようとする最後にここでそれを入れている:

lines = [] 
lines.push("ATT Wireless Bill") 
lines.push("") 
lines.push("Mobile Number:,770-555-1212") 
lines.push("item,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge") 
lines.push("") 
lines.push("1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00") 
lines.push("") 
lines.push("2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00") 
lines.push("") 
lines.push("1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00") 
lines.push("") 
lines.push("Mobile Number:,770-555-1213") 
lines.push("item,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge") 
lines.push("") 
lines.push("1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00") 
lines.push("") 
lines.push("2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00") 
lines.push("") 
lines.push("1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00") 
lines.push("") 
+0

ただ、コードスタイルのノートを、代わりに '場合(line.strip ==「」) ELSIFを書くの... '、line.strip.eql?(" ")... 1)空のif文を削除し、2)文字列の内容を比較するために' .eql? 'メソッドを使う必要があります。 http://ruby-doc.org/core/classes/String.html#M001122 – jefflunt

+0

「good_lines」とは何ですか?スタックの単なる実装ですか?コードが提供されていない(つまり、コードを提供していないか、それが何であるかを伝えている)わけではないため、自分の側でコードを動作させることはできません。 – jefflunt

+0

申し訳ありません - 完全なコードを提供していないため、関連性と簡潔性を保ちます。 good_linesは私の問題には必要ではなく、カウントも必要ありません。元の投稿を編集します。 – Scott

答えて

1

回答あなたはループ(lines.each)外cur_numを初期化しません。 したがって、cur_numは各ループで初期化されます。

私はundefined local variable or methodのエラーが予想されますが、if-branchが実行されない場合でも、各ループにcur_numが作成されているようです。あなたはcur_numを持っていますが、値なしで(またはそれ以上はありません)、それはゼロです。

Iは、コードが実行されていない場合でも、変数が作成されることを、示すために簡単な例を追加した:

if false 
    a = 1 
else 
    p a #works fine, a was created, but it is nil 
    p b #undefined local variable or method `b' 
end 

補遺II:

次のコードを示し、そのAをループ内の変数は 'loop internal'です。 2回目以降のサイクルは変数aなしで開始します。

#~ a = 0 # uncomment to compare 
5.times{ 
    if defined? a 
    puts "a is defined as #{a.inspect}" 
    else 
    puts "a is not defined" 
    a = 1 #define it now 
    end 
} 

関連質問:The scope is confusing


を私はあなたのコードビットを再設計。私はあなたのような文章を解析すると、私は正規表現でcase -statementを使用することを好む:

count = 0 
cur_num = "" 
DATA.each_line do |line| 
    case line 
    when /\A\s\Z*/ #skip empty lines 
    when /Mobile Number:,(.{12})/ 
     cur_num = $1 
     count = 1 
     puts "Current Number: #{cur_num}" 
     #puts "Object Type: #{cur_num.class}" 
    else 
     data = line.strip.split(',') 
     if data.length > 8 
     data.unshift(cur_num) 
     #if (count.modulo(10) == 0 || count == 1) 
      puts "[#{cur_num}] #{data.inspect}" 
      #pp data 
     #end 
     count += 1 
     end #(data.length > 8) 
    end #case line 
end 

__END__ 
ATT Wireless Bill 

Mobile Number:,770-555-1212 
item,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge 

1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00 

2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00 

1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00 

Mobile Number:,770-555-1213 
item,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge 

1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00 

2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00 

1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00 
0

2つのほとんど同一のバージョン、働いていた1、なかったものを比較し、1時間以上、この見つめてた後、私は1行をコメントアウトすることで失敗または成功させることができます。ここ は、私が実行している正確なコードです: [編集ノート、サンプルコードで垂直スクロールバーを防ぐために、コードを変更]

#!/usr/local/bin/ruby 
my_input ="ATT Wireless Bill\n\nMobile Number:,770-555-1212\n\nitem,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge\n\n1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00\n\n" 
my_input << "2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00\n\n1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00\n\nMobile Number:,770-555-1213\n\nitem,date,time,number called,rate period,plan type,minutes,airtime charge,ld charge,total charge\n\n" 
my_input << "1,2011-01-02,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00\n\n2,2011-01-03,6:56AM,404-555-1212,NW,UNW,4,0.00,0.00,0.00\n\n1,2011-01-03,7:56AM,404-555-1213,DT,UM2M,5,0.00,0.00,0.00\n\n" 
lines = my_input.split("\n") 
count = 0 
cur_num = "" # Line 7 - Comment out this line to see failure 
lines.each do |line| 
unless (line.strip.eql?("")) 
    if (line.slice(0,15) == "Mobile Number:,") 
    cur_num = line.slice(15,12) 
    count = 1 
    puts "Current Number: #{cur_num}" 
    #puts "Object Type: #{cur_num.class}" 
    else 
    data = line.strip.split(',') 
    if (data.length > 8) 
     data.unshift(cur_num) 
     #if (count.modulo(10) == 0 || count == 1) 
     puts "[#{cur_num}] #{data.inspect}" 
     #pp data 
     #end 
     count += 1 
    end 
    end 
    end 
end 

を私は7行をコメントアウトした場合、cur_valはライン18と20にnilであります。

誰かが理由を説明できますか? cur_num = ""なし答えWhy/How is my variable getting set to nil

+0

'cur_num =" "' cur_numを初期化しません(これはゼロです)。あなたのループは 'Current Number:'なしで開始するので、else-branch(cur_num = nil)に行きます。 – knut

+0

-----申し訳ありませんが、間違った投稿--- – knut

+0

私は理解していません。 cur_numは、18行目のunshift文の前に開始されます。その時点では、nilであってはなりません。なぜ、各反復の前に空の文字列を設定すれば、それは18行目の空の文字列ではありませんか?これは私には矛盾しているように見え、これはRubyの理解に必要な重要な概念だと思われます。 – Scott

関連する問題