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

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

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

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

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

Q&A

解決済

4回答

4228閲覧

uninitialized constant (NameError) の対処方法

kazuki0714

総合スコア28

Ruby on Rails 5

Ruby on Rails 5は、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Ruby

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

0グッド

2クリップ

投稿2019/07/25 05:32

編集2019/07/26 02:00

Rubyでテストを試したらスクショのようなエラーが発生しました。

他のrbファイルで定義したものを main.rb で実行しようとしました。

selfメソッドにしたり色々試したのですがエラーが直りません。(car.rb 中で @capacityself.capacity に変更したり)

原因わかる方、ご教授いただけませんでしょうか?

イメージ説明

【追記①】回答を参考に以下に直しましたが今度は NoMethodError が発生しました。
こちらの原因お分かりでしょうか?
またソースコードも修正しました。

イメージ説明

【追記②】

car.rbattr_accessor :capacity, :price, :speed を追加して出力したら上手く行ったんですが、
以下のように「アクセル良好」、「ブレーキ良好」が二重に出力されてしまいます。
これは if __FILE__ == $0 を出力してるのが原因でしょうか?

=> car.rb を修正して解決済み

イメージ説明

【追記③】アドバイスを元に何パターンか試しました。上手く行った部分もあるのですが出力の部分で苦戦してます。
requirerequire_relative 両方で上手くいった
Dir[File.dirname(__FILE__) + '/*.rb'].each {|file| require file } だとエラー発生
if __FILE__ == $0 だと上手く行くが puts だとエラーがでる

追記③の質問
if __FILE__ == $0 ではなく puts で出力する方法はどうすればいいか?(もう if __FILE__ == $0 するもんだと覚える方がいいのか)
Dir[File.dirname(__FILE__) + '/*.rb'].each {|file| require file } の正しい記述方法

お分かりであればお願いいたします。

↓こちらは上手くいった例

イメージ説明

if __FILE__ == $0 だと上手く行くが puts だとエラーになった例

イメージ説明

require ではなく Dir[File.dirname(__FILE__) + '/*.rb'].each {|file| require file } だと失敗

イメージ説明

【追記④】
Dir[File.dirname(__FILE__) + '*.rb'].sort.each {|file| require file } ではなく
Dir[File.dirname(__FILE__) + '/*.rb'].sort.each {|file| require file } でした。

これで実行すると下のスクショのように2度出力されてしまいます。
こちらの原因教えていただけますでしょうか?

![イメージ説明

File.join にしてもエラーになる(これはsort.eachにしてないから)

イメージ説明

File.joinsort.each を忘れずに書いても二重に出力されてしまいます

イメージ説明

Ruby

1# main.rb 2# Your code here! 3require './car' 4require './ferrari' 5require './honda' 6require './nissan' 7 8def main 9 10cars = [] 11 cars << Honda.new(8, 100, 10) 12 cars << Nissan.new(5, 50, 10) 13 cars << Ferrari.new(2, 200, 100) 14 15 cars.each do |car| 16 puts " 定員:#{car.capacity}人 価格:#{car.price}円 加速:#{car.speed}km 機能:#{car.accel},#{car.brake} " 17 end 18end 19 20if __FILE__ == $0 21 main 22end 23 24

Ruby

1# car.rb 2class Car 3attr_accessor :capacity, :price, :speed 4 def initialize(capacity, price, speed) 5 @capacity = capacity 6 @price = price 7 @speed = speed 8 end 9 10 def accel 11 p "アクセル良好" 12 end 13 14 def brake 15 p "ブレーキ良好" 16 end 17end 18 19

Ruby

1# ferrari.rb 2class Ferrari < Car 3end

Ruby

1# honda.rb 2class Honda < Car 3end

Ruby

1# nissan.rb 2class Nissan < Car 3end

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

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

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

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

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

guest

回答4

0

winterboum様、otn様の意見を参照にQiitaに分かりやすくまとめました。

https://qiita.com/kazuki0714/items/e3cb693e150168c07c0e

投稿2019/07/26 09:12

kazuki0714

総合スコア28

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

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

0

Ruby

1#main.rb 2 3# Your code here! 4# require ではなく Dir... にするとエラー発生 5 6require_relative "car" 7require_relative "ferrari" 8require_relative "honda" 9require_relative "nissan" 10 11def main 12 13cars = [] 14 cars << Honda.new(8, 100, 10) 15 cars << Nissan.new(5, 50, 10) 16 cars << Ferrari.new(2, 200, 100) 17 18 cars.each do |car| 19 puts car 20 end 21end 22 23if __FILE__ == $0 24 main 25end

Ruby

1# car.rb 2class Car 3 def initialize(capacity, price, speed) 4 @capacity = capacity 5 @price = price 6 @speed = speed 7 end 8 9 def accel 10 "アクセル良好" 11 end 12 13 def brake 14 "ブレーキ良好" 15 end 16 17 def to_s 18 " 定員:#{@capacity}人 価格:#{@price}円 加速:#{@speed}km 機能:#{accel}#{brake} " 19 end 20end 21

Ruby

1# ferrari.rb 2class Ferrari < Car 3end

Ruby

1# honda.rb 2class Honda < Car 3end 4

Ruby

1# nissan.rb 2class Nissan < Car 3end

投稿2019/07/25 08:37

kazuki0714

総合スコア28

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

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

0

今のエラーはotnさんのでクリアできますが、次に
cars.each do |car| でエラーになります

cars = Honda.new(100, 8, 10)
でなく
cars << Honda.new(100, 8, 10)
ですね

投稿2019/07/25 05:56

winterboum

総合スコア23284

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

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

kazuki0714

2019/07/25 06:40

ありがとうございます。 教えていただいた通りに修正したのですが次は2枚目のスクショのように `NoMethodError` が出ました。 こちらについても原因お分かりでしたら教えていただけますでしょうか?
otn

2019/07/25 06:48

そのメソッドを定義してないからです。
kazuki0714

2019/07/25 07:07

car.rb で @capacity = capacity としてるのですがそれだと定義されてないことになるのでしょうか?
otn

2019/07/25 07:08

はい。それはメソッド定義じゃないです。
kazuki0714

2019/07/25 07:20

すみません、知識不足なのですがメソッド定義する場合はどうすればいいか教えていただけますでしょうか? `car.rb` に `attr_accessor :capacity, :price, :speed` を追加したら3枚目のスクショみたいに出力できたのですが(別の問題発生しましたが。。。) これは定義とは違うのでしょうか?
otn

2019/07/25 07:23

それは定義ですが、オブジェクト指向的にはよいやり方ではないので、私の回答に追記しました。
guest

0

ベストアンサー

requireしてないからですね。
Dir[File.dirname(__FILE__) + '*.rb'].each {|file| require file }
が間違っている。

#追記
表示は、こうしたらよいと思います。

Ruby

12 cars.each do |car| 3 puts car 4 end 5

Ruby

1class Car 23 def to_s 4 " 定員:#{@capacity}人 価格:#{@price}円 加速:#{@speed}km 機能:#{accel},#{brake} " 5 end 6 ~~ 7end

#追記

以下のように「アクセル良好」、「ブレーキ良好」が二重に出力されてしまいます。

メソッドの中でも出力しているからですね。出力したくないなら、pを取れば良いです。

投稿2019/07/25 05:44

編集2019/07/25 07:27
otn

総合スコア84423

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

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

kazuki0714

2019/07/25 06:41

ありがとうございます! こちらは修正したコードのように全てのファイルを rewuire './car' require './ferrari' require './honda' require './nissan' のようにすればよろしいでしょうか?
otn

2019/07/25 06:46 編集

require_relative "car" などですね。 require → 実行時のカレントディレクトリ相対 require_relative → これを書いているスクリプトファイル相対 あるいは、元のコードを活かして、 Dir[File.dirname(__FILE__) + '/*.rb'].each {|file| require file } Dir[FIle.join(File.dirname(__FILE__) ,'*.rb')].each {|file| require file } パス名を + でつなげるときは、/ の有無に注意が必要なので、File.join を使うと良いです。
kazuki0714

2019/07/25 08:28

ありがとうございます。 一応できたのですが(追記③の1枚目のスクショ)2点疑問が残ってまして、 1. `if __FILE__ == $0` だと上手く行くが `puts car.main` だとエラーが出ます。`puts` で出力する場合はどういうコードを書けばよろしいでしょうか? それか 出力の時は `if __FILE__ == $0` を書くものだと覚えておけばよろしいでしょうか?(追記③のスクショ2枚目) 2. `Dir[File.dirname(__FILE__) + '/*.rb'].each {|file| require file } ` だとエラーが出るのですがどこか違ってますでしょうか?(追記③のスクショ3枚目)
otn

2019/07/25 09:23

1. 1枚目と同じく、mainと書けばいいのに、puts car.main とか書いているからですね。carは定義されていません。違うことを書くと違う結果になるのは当たり前です。何故違うことを書いた?? > 出力の時は `if __FILE__ == $0` を書くものだ 意味もわからず覚えるのはやめましょう。 2. 最初にcar.rbをrequireしないと、他のクラス定義がエラーになります。 "*.rb"だと順不同というか、ディレクトリ内部の物理順になるので、やっぱり駄目ですね。 たまたま、今回はcar.rbが辞書順に最初なので、~].sort.each{ ~ とsortを入れれば良いですが、辞書順にcar.rbより前のファイルが出来たら破綻します。
kazuki0714

2019/07/25 15:00

main にしたら出力されました、ありがとうございます。 requireの件ですがrequireの書く順番が大事ということでしょうか? 上から順番に読み取られるからディレクトリの順番をcar.rbを一番最後にすればいいということでしょうか?
otn

2019/07/25 15:05

> requireの件ですがrequireの書く順番が大事ということでしょうか? requireに限らず、プログラムは一般に書く順番が重要です。 > ディレクトリの順番をcar.rbを一番最後にすればいいということでしょうか? ??具体的にどういう意味でしょうか?
kazuki0714

2019/07/25 15:14

あっ、すみません僕の勘違いでした。 > たまたま、今回はcar.rbが辞書順に最初なので、~].sort.each{ ~ とsortを入れれば良いですが、辞書順にcar.rbより前のファイルが出来たら破綻します。 上記の部分がまだ理解できておらず、 `sort.each` を入れて `Dir[File.dirname(__FILE__) + '*.rb'].sort.each {|file| require file } ` としても `uninitialized constant Honda (NameError)Honda` と出てしまう状況でして 書き方が間違ってますでしょうか?
otn

2019/07/25 15:24

最初の間違いを直していないからです。
kazuki0714

2019/07/25 15:29

最初のとは 「requireしていない」 という部分でしょうか?
otn

2019/07/25 16:05

はい。2019/07/25 15:46 のコメント参照。
kazuki0714

2019/07/26 00:51

require_relative "car" require_relative "ferrari" require_relative "honda" require_relative "nissan" Dir[File.dirname(__FILE__) + '*.rb'].sort.each {|file| require file } ↑ こういうことでしょうか? 確かにこれでも実行できたのですが、 `Dir[File.dirname(__FILE__) + '*.rb'].sort.each {|file| require file } ` なしでもrequireだけで出力できるのでDir〜 は不要だと思ってました。
otn

2019/07/26 01:11

いや、+ '*.rb' じゃなくて、+ '/*.rb' だろうという指摘です。アドバイスが全く伝わってないということか。 直接require_relativeを並べて書くか、Dir~~~でループするかはどちらか選択です。
kazuki0714

2019/07/26 02:03

ありがとういございます。 + '/*.rb' だと出力されるのですが追記④のスクショのように二重に出力されてしまいます。 require だと上手く行ったのですが他の箇所に原因があるということでしょうか?
otn

2019/07/26 02:06

> 他の箇所に原因があるということでしょうか? そうですね。
kazuki0714

2019/07/26 02:13

cars.each do |car| puts car end の箇所とか色々試したのですが全部上手く行きませんでした。。。 修正箇所教えていただけますでしょうか?
kazuki0714

2019/07/26 02:37

なんとか解決しました。 `lib` フォルダを作ってそこに `car.rb` `ferrari.rb` `honda.rb` `nissan.rb` を入れて `main.rb` はそのフォルダに入れずに単体で置いといて読み込むと上手くできました。 私が書いたままだと、`Dir` で読み込まれて、さらに main.rb の最後の行で実行するから2回出力されるという認識でしょうか?
otn

2019/07/26 02:46

ああ、main.rb もrequiresされちゃいますね。 とりあえずは、ファイル名が自分のときはrequireしないように修正。
kazuki0714

2019/07/26 02:52

自分の認識間違ってましたでしょうか?(^◇^;) Dir のコードに何か加えるのでしょうか?
otn

2019/07/26 02:57

いや、11:37のコメントを見る前に書いたので、認識は合ってます。
kazuki0714

2019/07/26 03:05

よかったです。自分の中でちゃんと腹落ちしました。 長々とありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問