重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

すみません。Ruby言語で、loopメソッドの最後に、他の繰り返しで使った変数は使えませんとは、どういう事でしょうか?教えて頂けると幸いです。
で、[1, 2, 3].each{|i|p i}
{height : 170,weight : 60}.each {|element| p element }
みたいな感じのコードで、iやelementなどの変数は、eachメソッドのブロック内でのみ使えると書かれてありましたが、
loopメソッド内では、iなどの変数は使えないで、
例が、
ruby
loop do
puts i # ここでエラーが発生します
break
end
と例を挙げてくれましたが、では、なぜ、この例のloopメソッドには、変数が使えるのでしょうか?
以下のプログラムです。
num = 0
loop {
p num
num += 1
if num > 2
break
end
}
となっているのですが。これは、loopメソッド外で、変数が違うからでしょうか?又、iやelementがeachメソッド内のブロック内でしか使えないというのは、そういう規則だからですよね?教えて頂けると幸いです。

質問者からの補足コメント

  • うーん・・・

    いくつか質問があって、
    質問①「⑤はloopの外側ですが、numはloopの内側で更新されるので、3が印字されます。」
    の所で、特に、「loopの内側で更新される」とは、どういう意味でしょうか?
    質問②「puts "out:num2=#{num2}" #⑦」は、どうなるのでしょうか?
    もしかして、これが、エラーなのでしょうか?
    質問③「他の繰り返しで使った変数は使えません」については、結局、どういう意味でしょうか?
    以上3点について、教えていただけると幸いです。

    No.1の回答に寄せられた補足コメントです。 補足日時:2025/03/17 06:29
  • うーん・・・

    すみません。追加質問ですが、
    質問①の追加質問
    なぜ、3が印字されるのでしょうか?
    質問③の追加質問
    例えば、以下のようなプログラムでは、
    こちらから、例を挙げると、
    ~~ [ここから] ~~
    loop do
    i = 99
    puts i # i の値99が表示される
    break
    end

    loop do
    puts i # i が未定義でエラー
    break
    end
    ~~ [ここまで] ~~
    で、この場合だと、変数iの使い回しが出来ないということでしょうか?
    教えていただけると幸いです。

    No.2の回答に寄せられた補足コメントです。 補足日時:2025/03/17 18:35
  • 質問③の再追加質問
    上半分のコードだけなら 99 が表示され
    全体ならエラーとなり実行出来ません


    参考
    ~~ [ここから] ~~
    loop do
    i = 99
    puts i # i の値99が表示される
    break
    end

    loop do
    puts i # i が未定義でエラー
    break
    end
    ~~ [ここまで] ~~
    も、
    loop do
    i = 99 # 変数 i の有効範囲はここから
    puts i # i の値99が表示される
    break
    end # 変数 i の有効範囲はここまで
    #puts i # 変数 i の有効範囲外なのでエラー
    も、それらが、書籍の記述にある「他の繰り返しで使った変数は使えません」の意味なのでしょうか?

    No.3の回答に寄せられた補足コメントです。 補足日時:2025/03/18 22:53
  • うーん・・・

    繰り返し処理の構文(until式、for式、upto、downto、stepの構文)の説明の後に、loopメソッドの
    構文で、
    loop do
    処理
    end
    の書式をまとめたもので、
    その後に、この最後の一言で、「他の繰り返しで使った変数は使えません。」と、書かれてありました。
    で、loopメソッドのプログラムの例は、

    loop do
    p 1
    sleep 1
    end

    です。他の例のプログラムの例を挙げて欲しい(loopメソッドの例は、挙げたので、それ以外の例)とか、もし、情報不足で分からない部分がありましたら、聞き返して頂けると幸いです。

    No.4の回答に寄せられた補足コメントです。 補足日時:2025/03/19 19:02
  • うーん・・・

    迅速かつ懇切丁寧な回答ありがとうございます。
    わかりました。他の例のプログラムは、お礼のコメントの所に記述します。

    No.5の回答に寄せられた補足コメントです。 補足日時:2025/03/20 21:59
  • では、逆に、繰り返し使用できない変数もあるのでしょうか?
    これについても、もう解説済みなのでしょうか?
    教えて頂けると嬉しいです。

    No.9の回答に寄せられた補足コメントです。 補足日時:2025/03/22 01:44
  • うーん・・・

    いえ、ただ、繰り返し使用できない特殊な変数も存在するのかな?と思って、No.9の補足コメントに書かせて頂きました。
    ちなみになのですが、質問が2つほどあって、

    質問①No.6の回答で、(但し、「使いまわしできる」の正確な定義を行う必要はありますが、それは一旦置いておきます。」)と書いてありますが、どういう定義をするのでしょうか?

    質問②「他の繰り返しで使った変数は使いまわしできません」とあって、「使いまわしができる変数」と、「使いまわしができない変数」があると、記述がありますが、なぜ、「使いまわしができません」としか、書かれていないのでしょうか?今までの、話の流れだと、正確には、「使いまわしができない場合があります」が、正確だという事になりそうですが?なのに、なぜ、「使いまわしができない」と記述した訳が何かあるのでしょうか?tatsumaru77様は、どう思いますか?

    No.10の回答に寄せられた補足コメントです。 補足日時:2025/03/22 08:02
  • 本の題名は、
    「3ステップでしっかり学ぶRuby入門」
    で、著者は、「竹馬力」です。
    で、2018年1月26日に、紙版と電子版が出ています。
    以下のURLの通りです。

    https://gihyo.jp/book/2018/978-4-7741-9502-5

    よろしくお願いします。教えて頂けると嬉しいです。

    No.12の回答に寄せられた補足コメントです。 補足日時:2025/03/22 13:40
  • わざわざお骨折りありがとうございます。
    問題のページは、「127ページ」の「loopメソッド」の、すぐ下です。

    よろしくお願いします。教えて頂けると嬉しいです。

    No.13の回答に寄せられた補足コメントです。 補足日時:2025/03/22 14:17

A 回答 (13件中1~10件)

>本の題名は、「3ステップでしっかり学ぶRuby入門」


>で、著者は、「竹馬力」です。

ありがとうございました。そのサイトを見てみます。
この回答への補足あり
    • good
    • 0
この回答へのお礼

No.13です。
迅速な回答ありがとうございます。

お礼日時:2025/03/22 14:19

ちなみに、その本の題名は何でしょうか。


又、作者は誰でしょうか。
この回答への補足あり
    • good
    • 0
この回答へのお礼

No.12です。
迅速な回答ありがとうございます。

お礼日時:2025/03/22 13:34

>質問①No.6の回答で、(但し、「使いまわしできる」の正確な定義を行う必要はありますが、それは一旦置いておきます。

」)と書いてありますが、どういう定義をするのでしょうか?

回答:あなたが考えている「使いまわしできる」よくわからなかったので、まず、「使いまわしできる」とは、どういうことかをまず、明確にしてから、話を進める必要があると考えたからです。

「使いまわしできる」とはどういうことですか。と質問された場合、
あなたは、どのような説明をしますか。

私の考えている「使いまわしできる」とあなたの考えている「使いまわしできる」とが、食い違っている場合、話がおかしな方向に進む危険があるために、それを避けたかったので、正確な定義を行う必要があると書きました。


>質問②「他の繰り返しで使った変数は使いまわしできません」とあって、「使いまわしができる変数」と、「使いまわしができない変数」があると、記述がありますが・・・

回答:
最初に提示された質問では、
「他の繰り返しで使った変数は使えません。」とは書いてありますが、
「他の繰り返しで使った変数は使いまわしできません」とは書いてありません。
「他の繰り返しで使った変数は使えません。」と
「他の繰り返しで使った変数は使いまわしできません」とは、同じ意味ですか。
もし、同じなら、
「今までの、話の流れだと、正確には、「使いまわしができない場合があります」が、正確だという事になりそうですが?なのに、なぜ、「使いまわしができない」と記述した訳が何かあるのでしょうか?」
に対する回答は、その作者の書かれていることは正確でない、になります。
何故、作者がそのような記述をしたかは、私にはわかりません。
    • good
    • 0

>では、逆に、繰り返し使用できない変数もあるのでしょうか?


>これについても、もう解説済みなのでしょうか?

そのような変数はないと考えますが、
もし、あなたが何かを想定して、そのような質問をされているのなら、
質問の内容をもっと具体的に書いていただければ、より正確な回答を返すことができるかもしれません。
この回答への補足あり
    • good
    • 0
この回答へのお礼

No.10です。
迅速な回答ありがとうございます。

お礼日時:2025/03/22 07:38

3.下記の3つの式のケース


unitl式,while式,for式の場合、ブロックの中でのみ有効な変数という概念がありません。
ブロックの中でも外でも、同じ変数として扱われます。
以下のスクリプトを実行した場合のケースです。
ex5.rb
---------------------------
for i in [1, 2, 3] do
p "in: i=#{i}"
end
p "out: i=#{i}"
----------------------------
実行結果
"in: i=1"
"in: i=2"
"in: i=3"
"out: i=3"

変数iは、ブロックの中で宣言されていますが、ブロックの外でもその値を引き継いでいます。
上記はfor式ですが、while式、untile式でも同じ結果になります。


以上が、繰り返しの中で使用された変数に関する扱いとなります。
この回答への補足あり
    • good
    • 0
この回答へのお礼

No.9です。
迅速かつ懇切丁寧な説明ありがとうございます。

お礼日時:2025/03/22 01:41

2.ローカル変数(ブロック変数でない通常の変数)


No7では3つのメソッドのブロック変数について述べましたが、
ブロック変数以外の変数について述べます。
例として、以下のようなケースです。
変数 xはブロック変数ではありませんが、ブロックの中で使われている変数です。
この扱いについて述べます。
以下のようなスプリプとを作成し、実行します。
スクリプト名 ex3.rb
------------------------
1.upto(5) do |i|
p "in: i=#{i}"
x = 10 + i
p "in: x=#{x}"
end
p "out: x=#{x}"
-------------------------
実行結果
"in: i=1"
"in: x=11"
"in: i=2"
"in: x=12"
"in: i=3"
"in: x=13"
"in: i=4"
"in: x=14"
"in: i=5"
"in: x=15"
ex3.rb:6:in `<main>': undefined local variable or method `x' for main (NameError)

p "out: x=#{x}"
      ^
これは、変数 x がブロックの中で初めて宣言されているからです。
宣言とは、その変数にx値を設定することを言います。

ブロックの中で宣言されたローカル変数は、ブロックの外では、有効ではなくなります。
そのため、
p "out: x=#{x}"の個所で、エラーが発生します。

では、以下のようにした場合は、どうなるかです。
スクリプト名 ex4.rb
------------------------
x = 999
1.upto(5) do |i|
p "in1: x=#{x}"
p "in: i=#{i}"
x = 10 + i
p "in2: x=#{x}"
end
p "out: x=#{x}"
-------------------------
実行結果
"in1: x=999"
"in: i=1"
"in2: x=11"
"in1: x=11"
"in: i=2"
"in2: x=12"
"in1: x=12"
"in: i=3"
"in2: x=13"
"in1: x=13"
"in: i=4"
"in2: x=14"
"in1: x=14"
"in: i=5"
"in2: x=15"
"out: x=15"

1行目にx = 999があるので、xの宣言は、ブロックの前で行われたことになります。
そうすると、ブロックの中のxは、ブロックの外で定義されたxをそのまま引き継ぎます。
そして、ブロックを抜けた後でも、変数 xは有効でその値をそのまま引き継ぎます。

まとめると、以下のようになります。
ローカル変数がブロックの中で、宣言された場合は、ブロックの外では有効でなくなります。
ローカル変数がブロックの前で、宣言された場合は、ブロックの中では、その値をそのまま引き継ぎます。
そして、ブロックを抜けた後でも(ブロックの後でも)、その変数は有効で、使用することができます。
尚、この規則は、
loop do
p 1
sleep 1
end
のloop式に対しても適用されます。

until式、while式、for式には適用されます。
until式、while式、for式の場合については、次の回答で述べます。
    • good
    • 0
この回答へのお礼

追記(No.10の追加コメント)
No.7です。
No.10の補足コメントの2つの質問について、よろしくお願いします。すみません。No.10の補足コメントに、文字数の都合上、書き切れなかったので。
教えて頂けると幸いです。

お礼日時:2025/03/22 08:11

変数には、その変数の有効な範囲があります。


変数の種類ごとに有効な範囲が変わります。

1.ブロック変数
これは、提示された例では、以下の3つのメソッドのみに適用されます。
1.upto(10) do |i|
p i
end

10.downto(1) do |i|
p i
end
1.step(10, 2) do |i|
p i
end

上記の式で|i|のように||で囲まれた変数を言います。
|●|のように||で囲まれた変数(この場合は●)をブロック変数と呼びます。

ここでは、例として
1.upto(10) do |i|
p i
end
について、述べますが、他の2つのメソッドも同じです。

ここでは、ブロックの範囲の呼び方として
①より前の行をブロックの外(もしくはブロックの前)と呼びます。
②より後の行をブロックの外(もしくはブロックの後)と呼びます。
①~②の範囲をブロックの中と呼びます。
(他の2つのメソッドも同様です)

ブロックの外(ブロックの前)
1.upto(10) do |i|・・・①・・・ブロックの中
・・処理・・・      ・・・ブロックの中
end・・・・・・・・・・②・・・ブロックの中
ブロックの外(ブロックの後)

ブロック変数の有効範囲はブロックの中だけです。
ブロックの外では、その変数はなかったものとして扱われます。

例として以下のようなスクリプトを実行したとします。
説明上、画面への出力量を減らすため、upto(10)ではなくupto(5)にしています。
スクリプト名 ex1.rb
----------------------------
1.upto(5) do |i|
p "in: i=#{i}"
end
p "out: i=#{i}"
------------------------------
実行結果
"in: i=1"
"in: i=2"
"in: i=3"
"in: i=4"
"in: i=5"
ex1.rb:4:in `<main>': undefined local variable or method `i' for main (NameError)

p "out: i=#{i}"
      ^

上記のようなエラーとなり、
p "out: i=#{i}"
の行でエラーが発生します。
これは、|i|のiはブロックの外では有効ではないからです。

では、以下のようにした場合はどうなるかです。

スクリプト名 ex2.rb
----------------------------
i = 999
1.upto(5) do |i|
p "in: i=#{i}"
end
p "out: i=#{i}"
------------------------------
実行結果
D:\goo\ruby\scope>ruby ex2.rb
"in: i=1"
"in: i=2"
"in: i=3"
"in: i=4"
"in: i=5"
"out: i=999"

この場合、1行に設定された変数 i と ブロック変数 i とは全く別物です。
同じ変数名 i ですが、両者は、全く別々の変数であることにる留意してください。
それを踏まえると、ブロックの中では、iの値は1~5まで変化します。
ブロックの外では、1行目で設定されたiは999であるので、その内容が表示されます。

まとめると、上記のメソッドのブロック変数は、そのブロック内でのみ有効であり、
ブロックの外で、たとえ、同じ名前の変数が宣言されたとしても、その変数とは無関係である。
ということになります。
    • good
    • 0

あなたが、納得できないのは、


for式は、
for i in [1, 2, 3] do
p i
end

uptoメソッドは、
1.upto(10) do |i|
p i
end
となっているのに、
もし、「他の繰り返しで使った変数は使えません」というのなら、
for式でiを使っているからuptoメソッドでiを使えないはずで、
それなのに、uptoメソッドでiを使っているのは、どういうことだ。おかしいじゃないか。
ということでしょうか。

もし、「他の繰り返しで使った変数は使えません」ではなく、
「他の繰り返しで使った変数は使いまわしできません」ということであれば、納得できるでしょうか。
但し、「使いまわしできる」の正確な定義を行う必要はありますが、それは一旦置いておきます。
もし、納得できるなら、そのような意味に近いことを、伝えるために本の作者は
「他の繰り返しで使った変数は使えません」と書いたと考えられます。

しかしながら、「他の繰り返しで使った変数は使えません」では、あまりにも
大雑把でかつ不正確ですので、次の回答で、繰り返しで使う変数に関する扱いを述べます。
    • good
    • 0

他の例のプログラムの例もあげてください。


loopメソッドですが、
loop do
p 1
sleep 1
end
では、変数を使用していません。数字の1を表示して、1秒スリープしてます。よくわからないです。使用しているのは定数です。loopメソッドでは、どこで変数を使用しているのでしょうか。ますます、わからなくなってきました。
この回答への補足あり
    • good
    • 0
この回答へのお礼

until式は、
a=0

until(a>10) do
p a
a +=1
end

for式は、
for i in [1, 2, 3] do
p i
end

uptoメソッドは、
1.upto(10) do |i|
p i
end

downtoメソッドは、
10.downto(1) do |i|
p i
end

stepメソッドは、
1.step(10, 2) do |i|
p i
end

で、最後のloopメソッドのプログラムの例が、

loop do
p 1
sleep 1
end
という様にそれぞれのプログラムの例は、こんな感じです。
で、それぞれのプログラムの構文の説明が記述してあり、もう、本当に
最後の最後(loopメソッドの構文説明の後)に、「他の繰り返しで使った変数は使えません」と記述しているという様になっています。

教えていただけると幸いです。よろしくお願いします。もし、もう少し補足説明が必要なら、遠慮なく聞き返して下さい。

お礼日時:2025/03/20 22:34

>参考


>~~ [ここから] ~~
・・・途中省略・・・
>も、それらが、書籍の記述にある「他の繰り返しで使った変数は使えません」の意味なのでしょうか?

回答:
その書籍の「loopメソッドの最後に、他の繰り返しで使った変数は使えません」と述べているところと、それに関連して、提示されているスクリプトを
そのまま、全て、提示していただけませんでしょうか。
現状では、作者が、何を念頭に「他の繰り返しで使った変数は使えません」と言っているのかがわかりません。
この回答への補足あり
    • good
    • 0
この回答へのお礼

NO.4です。
迅速な回答ありがとうございます。

お礼日時:2025/03/19 18:41

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

このQ&Aを見た人はこんなQ&Aも見ています


このQ&Aを見た人がよく見るQ&A