<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/xml.xsl" type="text/xsl"?><feed xmlns="http://www.w3.org/2005/Atom">
  <title>nulog, NULL::something : out of the headphone &gt; 2004 &gt; September &gt; 05 &gt; Ruby プラグインっぽいもん</title>
  <link href="http://lowreal.net/logs/2004/09/05/4"/>
  <icon>http://lowreal.net/img/banner.png</icon>
  <link rel="self" type="application/atom+xml" href="http://lowreal.net/logs/2004/09/05/4.atom"/>
  <link rel="alternate" type="application/xhtml+xml" href="http://lowreal.net/logs/2004/09/05/4.xhtml"/>
  <updated>2004-09-05T14:26:07+09:00</updated>
  <author>
    <name>cho45(砂糖)</name>
  </author>
  <id>http://lowreal.net/2004/09/05/4</id>
  <entry>
    <title>Ruby プラグインっぽいもん</title>
    <link rel="alternate" type="text/html" href="http://lowreal.net/logs/2004/09/05/4.html"/>
    <link rel="alternate" type="application/xml+xhtml" href="http://lowreal.net/logs/2004/09/05/4.xhtml"/>
    <updated>2004-09-05T14:26:07+09:00</updated>
    <published>2004-09-05T14:26:07+09:00</published>
    <id>http://lowreal.net/2004/09/05/4</id>
    <category term="prog"/>
    <content type="xhtml" xml:base="http://lowreal.net/">
      <div xmlns="http://www.w3.org/1999/xhtml">
        <p>別ファイルに定義されたクラスを動的に読み直したいのだけど、どうやっていいやら。単に <code class="Ruby">eval</code> とかやると<q>同じクラス名はもう使ってるぜ？</q>って警告されるわけだし、<code class="Ruby">Class::new do ... end</code> は違うくさいし、<code class="Ruby">remove_const</code> はメソッド内から呼べない<span class="fn"><code class="Ruby">self.remove_const</code> がないよって怒られるわけだから、他に方法があるのかもしれない？ <ins datetime="2004-09-05T17:17:46+09:00"><code class="Ruby">定義したクラス名.class_eval("remove_const(:CONST)")</code>ってやればいいらしい（<a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/38594">[ruby-list:38594] Re: cgi.rbのremove_const</a>）。これで上手くいくかどうか実装してみよう。</ins></span>し。</p>
        <p>プラグインみたいな。ずっと動きっぱなしのプログラムで、ある一部分だけソースからもう一度読み直してやりたい。</p>
        <p># <abbr>ML</abbr> の過去ログで面白いのハケン <a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-list/27327">[ruby-list:27327] Haiku</a>. こういうの好き</p>
        <ins datetime="2004-09-05T17:27:13+09:00">
          <pre class="Ruby">
class PluginManager

    def initialize
        @plugins = {}
    end

    def class_name(filename)
        File::basename(filename, ".rb").capitalize
    end

    def load(filename)
        class_name = class_name(filename)
        eval(open(filename) {|f| f.read }, binding)
        # インスタンス作成して @plugin に突っ込む。
        eval("@plugins[class_name] = #{class_name}::new")
    end

    def unload(filename)
        class_name = class_name(filename)
        PluginManager.class_eval("remove_const(:#{class_name})")
        @plugins.delete(class_name)
    end

    def each
        @plugins.each do |k,v|
            yield k, v
        end
    end

end

pm = PluginManager::new
pm.load("foo.rb")
f = PluginManager::Foo::new
pm.unload("foo.rb")
f = PluginManager::Foo::new # =&gt; uninitialized constant PluginManager::Foo (NameError)

=begin
# foo.rb
class Foo
end
=end</pre>
          <p>みたいな感じかなぁ……もっとスマートにできるような気がする。しかもコレだと PluginManager の外からロードしたクラスにアクセスできる（丁度上の <var>f</var> のように ）んだよね。もう一個 Plugin クラスとか作ってその中にロードしたクラスのインスタンス突っ込んでやろうか。</p>
        </ins>
      </div>
    </content>
  </entry>
</feed>
