前田です。

>以前に僕がやってみたのより、よっぽどよさそうです。以前に質問したときに、
>まつもとさんに、Module#attr のような「メソッドをを追加するメソッド」を
>eval  を活用してできそうだ、といわれましたが、その一例をみたような気が
>します。自身もやってみたし、ヒントももらったんですが、どうも eval がイ
>ヤで、そこにコダワってしまって、違うやりかたを考えていたところです。

どうしてもこういうことをやろうとすると、evalを使わざるを
得なくなりますよね。
一応、汚い部分はユーザには見せないようにしたのですが(^^;

>一応、忘れているといけないのでいいますが、メソッドですから、foo?  みた
>いな名前もありうるので、実際につかうには、それをゴマカシてやらないとい
>けないと思います。

うっかりしていました。

--- once.rb.orig        Thu Jul  2 22:31:46 1998
+++ once.rb     Thu Jul  2 22:32:20 1998
@@ -15,8 +15,8 @@
   def def_once_i(name, id)
     eval %{
       def #{name}
-        def self.#{name}; @__#{name}__; end
-        @__#{name}__ = ONCE_METHODS[#{id}].call
+        def self.#{name}; @__#{name}; end
+        @__#{name} = ONCE_METHODS[#{id}].call
       end
     }
   end
@@ -27,8 +27,8 @@
   def def_once_i(name, id)
     module_eval %{
       def #{name}
-        def self.#{name}; @__#{name}__; end
-        @__#{name}__ = instance_eval(&ONCE_METHODS[#{id}])
+        def self.#{name}; @__#{name}; end
+        @__#{name} = instance_eval(&ONCE_METHODS[#{id}])
       end
     }
   end


># クラスメソッドってできるんでしょうか。

仮想クラスを使えばできると思います。

class << Foo
  def_once :foo do
    "foo"
  end
end

そういえば、このonceは各インスタンス毎に一回ずつ評価される
のですが、Eiffelの場合全部のインスタンスを通じて一回しか
評価されなかったような気がします。
どちらの動作が望ましいのでしょう。

--
前田 修吾