【Ruby】evalメソッドの役割と使い方【サンプル有り】
  • facebookページ
  • twitterページ
  • 2021.01.22

    【Ruby】evalメソッドの役割と使い方【サンプル有り】

    Rubyでプログラム開発に取り組んだことがある方は「eval」というメソッドが利用されているコードを見掛けたことがあるのではないでしょうか。

    本記事では、Ruby開発初心者の方にも分かりやすく、evalメソッドの役割と使い方をサンプルコードを掲載しながらご紹介していきます。

    Rubyのevalメソッドとは


    Rubyのevalメソッドとは、引数に設定した文字列をRubyのプログラムとして実行するメソッドです。

    evalはメタプログラミングで使用

    evalメソッドは少し専門的な言葉で表すと、メタプログラミングで利用するメソッドです。

    メタプログラミングとは、Wikipediaによると下記のように記述されています。

    プログラミング技法の一種で、ロジックを直接コーディングするのではなく、あるパターンをもったロジックを生成する高位ロジックによってプログラミングを行う方法、またその高位ロジックを定義する方法のこと。

    参考: メタプログラミング

    evalメソッドを使うメリットは?

    evalメソッドを使うメリットは、簡単に言ってしまうと何でも出来る点にあります。

    与えられた文字列をRubyのプログラムとして解析してくれるため、言ってしまえばRubyで出来ることは全て実現出来ることになります。

    またevalメソッドでは、指定した文字列がプログラムコードとして正しいかどうかを評価するため、実行するプログラムのエラーチェックとして利用することが可能です。

    evalメソッドを使う危険性も理解しよう

    evalメソッドは何でも出来る反面、危険性の高いメソッドとしても知られています。

    最も危険視すべき点は、開発者が予測出来ていないバグを生み出す可能性が非常に高いということです。

    プログラムコードとして成立している文字列であれば何でも実行出来てしまうため、例えばユーザーが入力した文字列をプログラムとして解析するような実装をしている場合、悪意のあるユーザーによってシステムが破壊されてしまう可能性も十分に考えられます。

    他にもevalを利用することによって、パフォーマンスの低下や可読性の低下を招く危険もあるため、使い所を慎重に見極めた上で利用する必要があります。

    Rubyでのevalメソッドの使い方


    では実際にRubyのevalメソッドはどのように記述して利用出来るのか確認していきましょう。

    基本構文

    Rubyのevalでは、下記の構文に沿って記述します。

    第1引数の「expr」は必須項目で、第2引数以降の値は任意で設定可能です。

    ポテパンダの一言メモ

    第3引数のfnameを省略した場合にはデフォルト値して「(eval)」、第4引数のlinenoを省略した場合にはデフォルト値として「1」が設定されます。

    第1引数: expr

    Rubyプログラムとして評価したい文字列を第1引数のexprに設定します。

    「サンプルを出力しています。」とコンソール出力したい場合には、下記のように記述します。

    実行結果

    第2引数: bind

    bindはBindingオブジェクトの略称で、変数やメソッドなどの環境情報を表すオブジェクトです。

    あるメソッド内のローカル変数を、evalで参照したい場合などに利用出来ます。

    エラーケース

    例えば下記の記述はエラーとなってしまいます。

    実行結果

    最初のeval内で設定した変数を保持したまま、別のeval処理で利用することは出来ないようです。

    Bindingオブジェクトを活用した記述方法

    上記のエラーをBindingオブジェクトを利用して記述し直すと、下記のように修正することが出来ます。

    実行結果

    今回の場合、local_variableというメソッドを作成しbindingオブジェクトを返却するように記述したことで、ローカル変数として定義されたtextにevalからアクセスすることが出来るようになりました。

    第3引数: fname

    fnameにファイル名を指定することで、exprに記述された文字列を指定したファイル名で実行されているかのように見せかけることが出来ます。

    例えば、実際にはsample.rbに記述されていた上記のRubyプログラムを、test.rbから実行されているかのように見せかけてみましょう。

    実行結果

    今回のサンプルでは、本来putsと記述しなければいけない箇所をputと記述し、わざとエラーを発生させています。

    実行結果にはtest.rbファイルの1行目でエラーが発生したかのように表示されています。

    第4引数: lineno

    linenoは第3引数と関連して、exprに記述された文字列をどのファイルの何行目かを指定して実行されているかのように見せかけることが出来ます。

    例えば第3引数の記述方法では、エラー発生箇所が1行目と表示されていましたが、第4引数に5と設定して改めて実行してみましょう。

    実行結果

    実行結果のエラー発生箇所が5行目と表示されていることをご確認頂けます。

    さいごに:Rubyのevalメソッドは安易に使わないように!


    本記事では、Rubyのevalメソッドについて、メソッドの役割から簡単な使い方をサンプルを交えてご紹介してきました。

    evalは非常に強力なメソッドであるため、使い方によっては深刻なバグに繋がる可能性も常に意識しておかなければいけません。

    evalを利用しなくても任意のプログラムを実現出来る方法が存在するケースは多く、まずはRubyのデフォルトやフレームワークで置き換えられるメソッドが提供されていないかを確認してみましょう。

    もしevalを利用しないと実現することが難しい場合には、思わぬバグを紛れ込ませないように入念に正当性チェックを行った上で利用するようにしてください。



    優良フリーランス案件多数掲載中!
    フリーランスエンジニアの案件をお探しなら
    ポテパンフリーランス

    この記事をシェア

    • Facebookシェア
    • Twitterシェア
    • Hatenaシェア
    • Lineシェア
    pickup









    ABOUT US

    ポテパンはエンジニアと企業の最適なマッチングを追求する企業です。

    READ MORE