

ディレクトリ内のファイルを読み込み、ファイルの内容を出力するプログラムを組んでいるのですが、

[code]

    in `read': Is a directory
    
[/code]

というエラーが出てしまいます。

おそらく、「それはディレクトリですよ」と言っていると思うのですが、その前の`if`文でファイルであることを確認してから処理を行なっているため、ディレクトリでなく、テキストファイルのパスであるはずです。

何故このようなエラーになってしまうのでしょうか。

## ソースコード

[code]

    require "find.rb"
    
    Find::find("/Users/tamada/Desktop/修論Dev/レシピデータパース用素材/テストデータ/recipe/") do |path| 
        if FileTest.file?(path) || FileTest.readable?(path) then
            # p "ファイル：" + path
            file = open(path)
            text = file.read
            p text
            file.close
        end 
    end
    
[/code]


CC BY-SA 3.0
2015-01-19T15:26:39.410
4856
2015-01-20T04:07:41.440
2015-01-19T17:18:17.627
30
2117
question
ruby
ディレクトリではないはずなのに、"Is a directory" というエラーが出る


（「解決しました」回答が消されてしまいましたが）解決した場合は、何が問題であったのかを記載すべきです。  
おそらく `if` 文の `FileTest.readable?(path)` が余計だったのだと思います。

  * `Find.find` メソッドは引数のディレクトリ以下のファイルを列挙します。そのとき、ディレクトリ自身を含みます。
  * `FileTest.#readable?` メソッドは読み込み権限があるかどうかを返すのでディレクトリでも `true` が返ります。

勝手ながらリファクタリングしました。

[code]

    require "find"
    
    Find.find("/Users/tamada/Desktop/修論Dev/レシピデータパース用素材/テストデータ/recipe/") do |path| 
      if FileTest.file?(path)
        open(path) do |f|
          puts f.read
        end
      end
    end
    
[/code]

ポイントを列記します。

  * `Kernel#require` メソッドの引数はライブラリ名のみにして拡張子は略します。（対照的に `Kernel#load` は拡張子必須です）
  * クラスメソッドで `Find::find` のように `::` を使う記法は古いです。 `Find.find` が一般的です。（ただ先日出た書籍「Effective Ruby」では古い記法でしたね^^;）
  * `if` 文で `then` を使わないのが Ruby 流です。
  * `Kernel#open` メソッドなどの IO を扱うメソッドでは、 close を忘れがちになるので使わずに、ブロックを用いるのが Ruby 流です。
  * `p` はデバッグ専用のメソッドと思った方が良いです。出力には `puts` を使いましょう。（まだデバッグ途中かもしれませんが）
  * 変数 `text` を使わずそのまま `p` / `puts` の引数に `file.read` / `f.read` を使った方が良いと思います。変数が少ない方が間違えにくいと思います。


CC BY-SA 3.0
2015-01-19T15:55:56.137
4859
2015-01-20T04:07:41.440
2015-01-20T04:07:41.440
4114
4114
4856
answer