質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.50%
Ruby

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

Q&A

解決済

3回答

12167閲覧

Ruby `<main>': undefined local variable or method `x' for main:Object (NameError)というエラーが出る。

hamham

総合スコア41

Ruby

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

1グッド

3クリップ

投稿2014/09/18 10:16

Ruby初心者です。
以下のプログラムを実行したらNameErrorというのがでました。
xという変数はあるのになぜこのようなエラーがでてるのですか?

lang

1[1,2,3].each do |i| 2 3x = i 4 5end 6 7puts x
DrqYuto👍を押しています

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

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

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

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

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

guest

回答3

0

ベストアンサー

スコープという、変数の有効範囲のような概念があります。
スコープは、変数の種類によって異なります。

  • グローバル変数

 $aのように$をつけた変数
スクリプト内全てでアクセス可能

  • インスタンス変数

 @aのように@をつけた変数
インスタンス内でアクセス可能

  • クラス変数

 @@aのように@@をつけた変数
そのクラスの全てのインスタンス内でアクセス可能

  • ローカル変数

 何もプレフィックスをつけていない変数
宣言されたメソッド内、ブロック内でアクセス可能

この例では、変数xはローカル変数であるため、each do 〜 endのブロック内でのみ有効となります。

変数のスコープの問題についての解決方法としては、

  1. グローバル変数を使う
  2. (例の実装が特定のクラス内であれば)クラス変数、もしくはインスタンス変数を使う
  3. ローカル変数xeach do 〜 endの外側で定義する

と言った方法があります。

ケースバイケースですが、この場合は3.のローカル変数をブロックの外側で定義するのが一般的でしょう。

lang

1x = 0 2[1, 2, 3].each do |i| 3 x = i 4end 5puts x

もしくは、ブロック内では変数の代入を行わず、戻り値として期待結果を返すように処理を変更してもよいと思われます。

この場合でしたら、下記のような実装になります。

lang

1x = [1, 2, 3].last # 最後の値を取得 2 3x = [1, 2, 3].inject(0) {|n, i| i } # 最後の値を取得

投稿2014/09/19 08:16

k.tada

総合スコア1679

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

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

hamham

2014/09/24 00:38

分かりやすい回答ありがとうございました!
guest

0

php で作業していた方は、不思議におもうのでしょう。

Rubyのスコープについて1:ローカル変数とグローバル変数 http://hoshiba2011.blog.fc2.com/blog-entry-10.html
を読んでみてください。

ブロック内で宣言されたものは、そのブロックの終わりまで有効
...
PHPの場合、宣言していない変数に対して参照したり、自己代入してもエラーにはならないので、Rubyの方がこの辺りは厳格ですね
...

どの言語でも入門のドキュメントには、変数の宣言、対応、スコープに関する事が述べられていると思います。
このことを理解していないと、ソースコードの意味を誤解してしまうし、解析・デバッグをしていくこともできません。

投稿2014/09/19 23:29

katoy

総合スコア22324

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

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

0

結論から申し上げますと、
eachブロック内で宣言した変数は、ブロックの外では
無効になります。
それで例外が発生しています。
以下のように修正すれば動くと思います。

lang

1[1,2,3].each do |i| 2 3puts i 4 5end

投稿2014/09/18 11:02

mamezou

総合スコア98

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問