« RubyとPHPの優劣 | トップページ | 弟が亡くなって3年が経ちました »

2007/10/28

class_exists on Ruby

PHPには、class_existsというクラスの有無を確認する関数があります。
いくつかの動作環境でスクリプトを実行する際に、特定のクラスがあるか無いかを判断してスクリプトを切り替えるのにとても役立ちます。

では、同じ事をRubyでやろうと思ったら...見つかりません。多分、僕の探し方が悪いせいだと思うのですが、わかりませんでした。そんな中、一昨日のRuby認定試験対策に参加して、rescueという構文を知ったのでこれを使って早速作ってみる事にしました。rescueはJAVAでいうTry .. cach文になるのかな。

begin
  実行したいスクリプト
rescue
  エラーが発生した場合に実行するスクリプト
end
という使い方になります。
簡単な例を示すと、
begin
  tmp = CGI.new()
  flg = true
rescue
  flg = false
end
  
if flg then
  print "CGIクラスはあります"
end
となります。では、class_existsの構文は
class_exists(クラス名)
なので、これに合わせて作ってみると、
def class_exists(name)
  begin
    eval "tmp = #{name}.new"
    flg = true
  rescue
    flg = false
  end
  return flg
end
という感じですね。 ただ、evalを使用するのには多少不安を感じるので、何か対策が必要かもしれません。とりあえず、";"は何か別の文字に置き換えるか、";"があったらfalseを返すとかした方が良いかもしれません。

ということで、

name.gsub!(/;/,'')
を追加しましょう。完成形は以下となります。
def class_exists(name)
  name.gsub!(/;/,'')
  begin
    eval "tmp = #{name}.new"
    flg = true
  rescue
    flg = false
  end
  return flg
end
「こんなの当たり前だろ」という声が聞こえてきそうですが、あえて恥をさらしてみました。誰かの役に立ちますでしょうか。

で、僕はこれを何に使うかというと、作っているWebフレームワークでWebrickとmod_rubyのどちらかを判断して実行できるようにするために使用します。
明日には他の問題も修正したバージョンを公開したいと思っています。

|

« RubyとPHPの優劣 | トップページ | 弟が亡くなって3年が経ちました »

コメント

Objecct#is_a? Classで判断してみては?

newしてしまうと副作用が大きいと思います。initializeメソッドの引数によってはうまく動かないし。

evalを使わずにclassを得る方法として名前を"::"でsplitしてModule#const_getで下位のオブジェクトを辿っていくという手もあります。

投稿: MoonWolf | 2007/10/29 20:12

MoonWolfさん、コメントありがとうございます。
ご指摘の通り、newには問題ありですよね。引数が無いと上手く動かないものも非常に多いですし...
「Object#is_a? Class」についてですが、これはインスタンスのクラスを調べるものという認識でいたのですが、こういう場合にも使えるのですか?ちょっと調べてみたいと思います。
有益な情報をありがとうございます。

投稿: きむらしのぶ | 2007/10/30 06:08

コメントを書く



(ウェブ上には掲載しません)




トラックバック

この記事のトラックバックURL:
http://app.cocolog-nifty.com/t/trackback/79953/16895792

この記事へのトラックバック一覧です: class_exists on Ruby:

« RubyとPHPの優劣 | トップページ | 弟が亡くなって3年が経ちました »