2011-12-09 2 views
1

私はパッケージに "autorequire"を作成しようとしています。つまり、Rubyが未知の定数に遭遇した場合、要求が成功すると中断した箇所に進みます。私が予想したように、それはHello, Hello, World!を出力します未知の定数を要求して続行する

autoload { 
    print "Hello, " 
    x = ArrayFields.new 
    x << "World!" 
    puts x[0] 
} 

のようにこれを使用するのであれば

def autoload(&block) 
    yield 
rescue NameError => e 
    if e.message[/constant/] 
    require e.name.to_s.downcase rescue LoadError raise 
    retry 
    end 
    raise 
end 

:今、私はこのような何かを持っています。したがって、定数の必要性を処理しますが、先頭から指定されたブロック全体を実行します。では、どのように失敗したのかを私はどのようにスキップしますか?これは主に学術的興味のためで、私はこのような試みのあらゆる危険にも興味があります。

答えて

3

レスキュー句の例外の直前に戻ることはできません。あなたが望むことを実行するためのより実現可能なアプローチは、const_missingを上書きすることです。

+0

元のエラー(初期化されていない定数)を保持するために、そのドキュメントで与えられた例を変更しました。しかし、なぜこれが1つのライナーとして機能しないのですか? 'ファイル救済が必要です。LoadError super.const_missing(name)'。 –

+0

@Tatu:インラインレスキューのシンタックスは 'exp1レスキューexp2'です。これは、' begin require file rescue LoadError super.const_missing(name)end'と書かれています。インラインレスキューを使用して例外タイプを指定することはできません。 – sepp2k

+0

それはタイプミス(構文は許可されていますが)でしたが、それとあなたのリマインダが私になぜそれが動作しないのかを理解させました。 LoadErrorはStandardErrorではないため、型のないレスキューではキャッチされません。後者の例でもこれを覚えておくと良いでしょう。レスキューが1行に書かれているかどうかにかかわらず、レスキューが自分の行になければ、常にインラインレスキューです。 –

0

Rubyにはautoloadがあり、少なくともRuby 2.0には存在します。

+0

ルビーのオートロードは、OPのコードとは何か異なります(つまり、ルビの自動ロードでファイルを「事前登録」する必要があります)。 – sepp2k

関連する問題