1

前の質問 ( Rubyのメソッドはサブルーチンに似ていますか? ) で、Ruby のメソッドについて尋ねました。今、初めてのメソッドを書いていると、明らかに変数のスコープに問題が発生しました。メソッドを呼び出さない場合、以下のプログラムは解釈して正常に実行されますlearn。つまり、33 行目の呼び出しを削除すると、すべて正常に動作し、メイン プログラムとメソッドの両方でlearn(2)さまざまな変数 (たとえば ) を使用しても問題ないように思われます。stimulus[]しかし、呼び出しを挿入すると (そしてuキーを押して使用すると)、以下のメッセージが表示さstimulusれ、メソッドで使用するのは適切ではないことがわかります。

brain.rb:26:in `block in learn': undefined local variable or method `stimulus' for main:Object (NameError)
    from brain.rb:25:in `each'
    from brain.rb:25:in `learn'
    from brain.rb:33:in `ucr'
    from brain.rb:69:in `<main>'

しかし、私はそこでそれ(および脳)を使用する必要があり、メインプログラムによって決定される現在の値を使用します。私が遭遇したスコープに関する質問へのすべての回答は、逆の方向に進んでいるように見えます。つまり、メソッド内で変数を使用する際の問題です。刺激と脳をグローバルにしようと思ったのですが、どうやらそれはダメみたいです。プログラムから変数を使用するようにメソッドに指示するにはどうすればよいですか?

Ps。このメソッドが機能したら、プログラムの他の 6 つの場所から呼び出します。

require 'matrix'
class Matrix
  def []=(i, j, x)
    @rows[i][j] = x
  end
end #code to allow putting individual elements in matrix at i,j
def read1maybe
  return $stdin.read_nonblock 1
rescue Errno::EAGAIN
  return ''
end # part of code to get keypress
brain=  Matrix[ [0,0,0,0,99,0,0,0,0,1,0],
                [0,0,0,0,0,99,0,0,0,1,0],
                [0,0,0,0,0,0,99,0,0,1,0],
                [25,0,0,0,0,0,0,1,-1,1,-99],
                [0,23,0,0,0,0,0,1,-1,1,1],
                [0,0,24,0,0,0,0,1,-1,1,1],
                [0,0,0,22,0,0,0,1,-1,1,1] ]
stimulus=Matrix.column_vector([0,0,0,0,0,0,0,0,0,0,0])
behavior=Matrix.column_vector([0,0,0,0,0,0,0])
t=500 # t=threshold
energy=50
# begin defining behavioral methods
def learn(ix)
    for j in (7..10)
    if stimulus[j]>0 && brain[ix,j] != 0 && brain[ix,j] < 99 then
        brain[ix,j]+=int(0.1 * stimulus[j]) * (99-brain[ix,j])
    end # if stim
    end # for j
end # learn
def ucr
    puts "Show UCR"
    learn(2)
end
def positive_fixer
    puts "Positive fixer"
end
def negative_fixer
    puts "Negative fixer"
end
# end defining behavioral methods

# begin main program
while(energy>0) do
(0..10).each {|n| if stimulus[n,0]>2 then stimulus[n,0]+= -2 else stimulus[n,0]==0 end}
input=false
system 'stty cbreak'
look=0
while look < 40000
  q = read1maybe
  break if q.length > 0
  look +=1
end # while look
case q
when "f" then stimulus[4,0]=9 and puts "Good!"
when "p" then stimulus[5,0]=9 and puts "Bad!"
when "u" then stimulus[6,0]=9
when "l" then stimulus[7,0]=9 and stimulus[8,0]=9 and puts "ight on"
when "c" then stimulus[9,0]=9 and puts "   BUZZZ"
input=true
end # case q
system 'stty cooked'

if input==false then (0..3).each { |n| stimulus[n,0]=rand(25)} end

behavior=brain*stimulus
if behavior[0,0] > t then positive_fixer end
if behavior[1,0] > t then negative_fixer end
if behavior[2,0] > t then ucr end
if behavior [3,0] > t then puts "show operant 1" end # and stimulus[10,0]=9
if behavior[4,0] > t then puts "show operant 2" end
if behavior[5,0] > t then puts "show operant 3" end
if behavior[6,0] > t then puts "show operant 4" end
energy += -1
# temp to test development of memory
puts brain[2,9]
end # while energy > 0
puts
puts "It's dead Jim."
# end main program
4

1 に答える 1

1

stimulusメソッドの外でbrain宣言されています。次のようにパラメータとして渡す必要があります。

def learn(ix, brain, stimulus)
    for j in (7..10)
    if stimulus[j]>0 && brain[ix,j] != 0 && brain[ix,j] < 99 then
        brain[ix,j]+=int(0.1 * stimulus[j]) * (99-brain[ix,j])
    end # if stim
end # for j end # l

ucrそして、次のように編集します。

def ucr(brain, stimulus)
    puts "Show UCR"
    learn(2, brain, stimulus)
end

ucrそして、のように呼び出しucr(brain, stimulus)ます。パターンが見えますか?パラメータを使用するメソッド定義にパラメータを追加し、メソッドの呼び出し時にそれらを渡す必要があります。

于 2012-08-22T23:30:11.443 に答える