- ベストアンサー
Rubyの関数定義
Rubyで関数を定義し、呼び出すとエラーになります。 sub1() #sub1の呼び出し ・・・ def sub1() ・・・ end のようにすると、エラーになります。 def sub1() ・・・ end sub1() #sub1の呼び出し のようにするとエラーになりません。 関数の定義を呼び出し箇所のソースの後ろで定義してもエラーにならない方法はないのでしょうか。 ご存じのかた、いらしたら教えて下さい。
- みんなの回答 (1)
- 専門家の回答
質問者が選んだベストアンサー
こんばんは。 私の手に余りそうですが、できる範囲でお答えを。 細かいところで間違いはあるかもしれません。 >関数の定義を呼び出し箇所のソースの後ろで定義してもエラーにならない >方法はないのでしょうか。 えっと、ありません。……じゃ愛想なさすぎですか。 現状の仕様では具体的にどのような不都合がございますでしょうか。 普通はクラスやメソッド定義は別ライブラリファイルにまとめておいて 最初にライブラリを require するのが(特に)Ruby の流儀だと思います。 Perl だったら以下のように手続きの定義を後に書いても動きますね。 sub1("camel"); sub sub1 { my($arg) = @_; print "Hello, ", $arg, ".\n"; } しかし、まだ呼び出しの時点で定義されていないメソッドを使うのは 可読性を損なうことにはならないでしょうか。 メソッド定義を後回しにしたコードが動かないのは、 このことを危惧したまつもとさんの思想のような気がします。 「見かけ上」定義を後回しにする汚い裏技はこのようになるでしょうか。 あなたが本当にやりたいことからは外れるかもしれませんが。 #!/usr/local/bin/ruby #class Object def method_missing(name, *args) defun = DATA.read eval defun send(name, args) end #end greet "world!" __END__ def greet(someone) puts "Hello, " << someone end Ruby スクリプトの「__END__」以降の行は DATA という File オブジェクトとしてアクセスできます。 未定義のメソッドが起動されたタイミングでフックされる Object#method_missing を再定義しておいて、 DATA にあるメソッド定義を評価するというシナリオ。 以下余談です。 Ruby のすべてのオブジェクトが属する Object クラスにはもれなく、 Kernel モジュールによって method_missing メソッドが用意されています。 このメソッドは、レシーバオブジェクト(self)に対して呼び出された メソッドが定義されていないときに起動されます。 「NoMethodError: undefined method ...」などという デフォルトのエラーメッセージはRuby インタプリタ自身というより この method_missing が出しているのです。 それが証拠に、このメソッドを再定義することによって エラーメッセージを変えたり、または空の定義をすることで エラーがなかったことにさせることもできます。 Ruby で関数のように見えるのは、 実はレシーバがトップレベルの Object であるプライベートメソッド (「レシーバ.メソッド」の形で書けないメソッド)で、 このような関数風メソッドは Kernel モジュールで定義されています。 すなわち「func(args)」は「Kernel.func(args)」に等しく、 しかしてその実体は「Kernel.send(:func, args)」であります。 「Kernel.」を略せるのは、Object クラスが「include Kernel」しているからで、 「include Math」すると今まで「Math.cos Math::PI」としか書けなかったのが 「cos PI」と書けるのと同じです。 もっと突っ込んだ質疑をなさりたいなら、Ruby 一般についての メーリングリスト ruby-list に登録されるといいでしょう。 まつもとさんからの回答メールも直に読めます。 購読されるには、ruby-list-ctl@ruby-lang.org まで 「subscribe (あなたのお名前)」という内容のメールを投げてください。 件名は空でも構いません。その後折り返し確認メールが来ます。 今は Windows で Internet Explorer とのインターフェイスに ついての話題に花が咲いてますね。
お礼
回答ありがとうございました。 >>関数の定義を呼び出し箇所のソースの後ろで定義してもエラーにならない >>方法はないのでしょうか。 >えっと、ありません。……じゃ愛想なさすぎですか。 >現状の仕様では具体的にどのような不都合がございますでしょうか。 まず、これがrubyの仕様なのかどうかの確認がしたくて、質問しました。仕様であれば、仕方ないですね。 現状に仕様に対する不都合は、 1.今まで、私はmainの関数を最初に書き、以下それから呼び出される関数を、逐次その後に書いていくという方法を採用していました。(C,Perl等で)それで、できれば、その方法を踏襲したいと言う希望です。 2.又、呼び出す関数が、常に、その前に定義していないと、エラーになるということは、関数から関数を呼び出す場合でも、常に、関数の記述の順序を意識しないといけないと言うことになります。このことを意識せずにコーディングしたいということです。 -------------------------------------------- 例えば、C言語の場合では、関数のプロトタイプ宣言のみをプログラムの先頭で行って、実際の処理の部分は、後で、記述する方法が、一般的に採用されています。Rubyの場合でも、もしかしたらこのような方法があるかも知れないと思い質問した次第です。 Rubyに関しては、まだ始めたばかりですので、当面は、最初に関数を定義し、その後、呼び出す方法をとりたいと思います。もう少し、Rubyになれてきましたら、メーリングリストに本件、Rubyに対する希望として、投稿したいと思っております。 この回答で、私の知りたいことが、十分判明致しました。ありがとうございました。