🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Q&A

解決済

2回答

473閲覧

rubyのローカル変数のスコープについて

rm11_j

総合スコア4

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

1グッド

1クリップ

投稿2021/03/03 06:53

##Rubyのローカル変数のスコープについて
タイトルの通りです。Rubyのローカル変数のスコープについて質問です。
私はローカル変数とはブロック・メソッド内で定義された変数のことで、またメソッド・ブロック内からは外部で定義した変数を参照できない(引数として渡さない限り)と理解しています。

ruby

1x = 1 2 3def calculate 4 puts x 5end 6 7calculate

このようなコードをターミナルから実行するとundefined local variable or method `x' for main:Object (NameError)というエラーが出ました。
これはcalculateメソッド内で変数xが定義されていないというエラーです。
つまりdefの外、rubyのトップレベルで定義したxはメソッド内からは参照できないということですよね。

ruby

1x = 100 2 3while true do 4 if x > 0 5 puts "0より大きい" 6 break 7 else 8 puts "0より小さい" 9 break 10 end 11end 12

次に上記のファイルをターミナルで実行しました。
すると「0より大きい」というターミナルに出力されました。
つまりトップレベルのx = 100はブロック内でも参照可能ということですよね。

ブロック・メソッド内からは外で定義した変数は参照できないならば今回もエラーが出るはず(do~end内でxを定義したわけではないから)と思ったのですがなぜでしょうか?

ozwk👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

そもそも、Rubyのwhileforはブロックを形成しません。

ブロックの場合、
・ブロック内からブロック外のローカル変数は読み書きできる
・ブロック外に無く、ブロック内だけで使われるローカル変数は、ブロック実行毎に生まれて消える
(当然、ブロックの外では消えた後なので、参照できない)

2つめの規則から、
「ブロック内でしか使わないんだけど、ブロックを繰り返し実行する際に、前回の値を保持して欲しい」
という変数も外側で定義しておく必要があります。

Ruby

15.times do |i| 2 if i % 2 == 0 3 x = i 4 else 5 p x 6 end 7end

では、nilだけが表示され、この前にx = nilを入れると挙動が変わります。
このためだけに、ブロックの前で変数定義するのはちょっとやな感じですけど。

投稿2021/03/03 11:55

otn

総合スコア85882

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rm11_j

2021/03/03 13:54

回答ありがとうございます。 1つだけ質問がありますl。do endや{}はブロックの記述法だと理解しているのですが、while 条件式 do ~ endのdo~endはwhile文の書き方がたまたまブロックと一致しているだけでwhile文におけるdo-endはブロックではない、ということですか?
otn

2021/03/03 14:15

その通りです。 Rubyだとwhileやforはあまり使いませんが、使うときでも普通はdoを書かないと思います。ifのthenを書かないのと同じ。 while xxx; yyy end と1行に書く場合は while xxx do yyy end とセミコロンを書くのを避けてdoを書くこともあるかも知れません(書かないかも知れません)。まあ、あまり1行に書くということは無いと思いますが。
guest

0

ブロック・メソッド内からは外で定義した変数は参照できないならば

この前提が誤りです。ブロック内からは、外側の変数も参照できます

投稿2021/03/03 06:56

maisumakun

総合スコア145963

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

rm11_j

2021/03/03 07:43

回答ありがとうございます。 ローカル変数はブロック内でのみ扱える?(ソースは忘れましたすみません...)といった記述を過去に読んだ気がするのですが、ブロック内で定義したローカル変数は外部から参照できない、というのは正しいでしょうか?
maisumakun

2021/03/03 07:53

> ブロック内で定義したローカル変数は外部から参照できない、というのは正しいでしょうか? はい、そちらは正しいです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問