«前の日記(2005年01月13日) 最新 次の日記(2005年01月15日)» 編集

Matzにっき


2005年01月14日 [長年日記]

_ 知識共有を基盤とした高度造船CIMの開発研究

Webを眺めてたら、ふとしたことから前の会社でやってたプロジェクトの報告書に行き当たる。 懐かしい。

1997年に前の会社を辞めてるから、この報告書は私が辞めてから書かれたものだよな。 実はこのGPMEの一部にはRubyが組み込まれていたのだが、今となっては誰が知るだろうか。

というか、この時の成果っていったい今どうなってるんだろう。 全然使われていないような気がするんだけど。だとしたら、もったいない。オープンソースにしておけば。

_ Famous and not so famous programming quotes

RedHandedから。

このページを作ったArmin Roehrlは、自著である 「Programmieren mit Ruby」 (ISBN 3-89864-151-1)で、各章ごとにやたら面白い引用を付けていた(献本されたのを眺めてて、そこだけは英語だったので分かった)のだが、こんなページを持っていたとは。

私の言葉が結構載っている。こんな面白いこと書いたっけか(自画自賛)。 いずれにせよユーモアは重要だよな。

_ [言語]Python in What's Ruby

ブラジルからメールをもらう。 要約すると

  • What's Ruby」をポルトガル語に翻訳して紹介した。
  • Python エバンジェリストが「間違ってる。Python 2.2からはすべてがオブジェクトだ」と文句を付けた
  • 私には判断つかないんだけど、彼の言ってることは正しいの?

というような内容。どうやら、

Ruby is a complete, full, pure object oriented language: OOL. This means all data in Ruby is an object, not in the sense of Python or Perl, but in the sense of Smalltalk: no exceptions. Example: In Ruby, the number 1 is an instance of class Fixnum.

という内容がブラジルのPythonエバンジェリストのお気に召さなかったらしい。 この文章を書いた時点では確かにそうだったんだけど、 そういえばnew style classとかが導入された時に、整数とかも含めてすべての「オブジェクト」はなんらかのクラスの「インスタンス」になったんだっけか。

で、調べてみる。やはり実際にPythonを起動するのがよいだろう。 irb相当が直接実行できるのは便利だ。

# python
Python 2.3.4 (#2, Jan  5 2005, 08:24:51) 
[GCC 3.3.5 (Debian 1:3.3.5-5)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> type(1)
<type 'int'>
>>> int
<type 'int'>
>>> class Int(int):
...    pass
... 
>>> Int()
0
>>> Int(256)
256
>>> type(Int(256))
<class '__main__.Int'>

確かに。ちゃんとintのサブクラスも作れる。じゃあ、intクラスにはどんなメソッドがあるのだろう。 確かPythonはdocstringがついてるって自慢してたな。

>>> print int.__doc__
int(x[, base]) -> integer

Convert a string or number to an integer, if possible.  A floating point
argument will be truncated towards zero (this does not include a string
representation of a floating point number!)  When converting a string, use
the optional base.  It is an error to supply a base when converting a
non-string. If the argument is outside the integer range a long object
will be returned instead.

あれれ、変換関数のドキュメントだよ。おかしいな。

では、リフレクションを使って確認しよう。

>>> int.__dict__
<dictproxy object at 0xb7e2944c>
>>> int.__dict__.keys
<built-in method keys of dictproxy object at 0xb7e29464>

うーむ、わからない。ループを回せばよいのかな。

>>> for i in int.__dict__.keys:
...   print i
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: iteration over non-sequence

だめだ。結局、ソースを読んで確認した(ここでドキュメントを探さないところがアレだけど)、 <type 'int'>(クラス)には唯一 __getnewargs__ というメソッドがあるらしい。

>>> 1.__getnewargs__()
  File "<stdin>", line 1
    1.__getnewargs__()
                   ^
SyntaxError: invalid syntax

あらら、そうか。「1.」は構文解析できないのか。

>>> (1).__getnewargs__()
(1,)

これはたぶんシリアライズかなにかに使うんだろうな。 うーむ、勝手が違って使いにくい。

あ、riに対応するpydocってプログラムがあるんだっけ。

% pydoc int
Help on class int in module __builtin__:

class int(object)
 |  int(x[, base]) -> integer
 |  
 |  Convert a string or number to an integer, if possible.  A floating point
 |  argument will be truncated towards zero (this does not include a string
 |  representation of a floating point number!)  When converting a string, use
 |  the optional base.  It is an error to supply a base when converting a
 |  non-string. If the argument is outside the integer range a long object
 |  will be returned instead.
 |  
 |  Methods defined here:
 |  
 |  __abs__(...)
 |      x.__abs__() <==> abs(x)
 |  
 |  __add__(...)
 |      x.__add__(y) <==> x+y
 |  
 |  __and__(...)
 |      x.__and__(y) <==> x&y
 |  
 |  __cmp__(...)
 |      x.__cmp__(y) <==> cmp(x,y)
 |  
 |  __coerce__(...)
 |      x.__coerce__(y) <==> coerce(x, y)
 |  
 |  __div__(...)
 |      x.__div__(y) <==> x/y
 |  
 |  __divmod__(...)
 |      x.__divmod__(y) <==> xdivmod(x, y)y
 |  
 |  __float__(...)
 |      x.__float__() <==> float(x)
 |  
 |  __floordiv__(...)
 |      x.__floordiv__(y) <==> x//y
 |  
 |  __getattribute__(...)
 |      x.__getattribute__('name') <==> x.name
 |  
 |  __getnewargs__(...)
 |  
 |  __hash__(...)
 |      x.__hash__() <==> hash(x)
 |  
 |  __hex__(...)
 |      x.__hex__() <==> hex(x)
 |  
 |  __int__(...)
 |      x.__int__() <==> int(x)
 |  
 |  __invert__(...)
 |      x.__invert__() <==> ~x
 |  
 |  __long__(...)
 |      x.__long__() <==> long(x)
 |  
 |  __lshift__(...)
 |      x.__lshift__(y) <==> x<<y
 |  
 |  __mod__(...)
 |      x.__mod__(y) <==> x%y
 |  
 |  __mul__(...)
 |      x.__mul__(y) <==> x*y
 |  
 |  __neg__(...)
 |      x.__neg__() <==> -x
 |  
 |  __nonzero__(...)
 |      x.__nonzero__() <==> x != 0
 |  
 |  __oct__(...)
 |      x.__oct__() <==> oct(x)
 |  
 |  __or__(...)
 |      x.__or__(y) <==> x|y
 |  
 |  __pos__(...)
 |      x.__pos__() <==> +x
 |  
 |  __pow__(...)
 |      x.__pow__(y[, z]) <==> pow(x, y[, z])
 |  
 |  __radd__(...)
 |      x.__radd__(y) <==> y+x
 |  
 |  __rand__(...)
 |      x.__rand__(y) <==> y&x
 |  
 |  __rdiv__(...)
 |      x.__rdiv__(y) <==> y/x
 |  
 |  __rdivmod__(...)
 |      x.__rdivmod__(y) <==> ydivmod(y, x)x
 |  
 |  __repr__(...)
 |      x.__repr__() <==> repr(x)
 |  
 |  __rfloordiv__(...)
 |      x.__rfloordiv__(y) <==> y//x
 |  
 |  __rlshift__(...)
 |      x.__rlshift__(y) <==> y<<x
 |  
 |  __rmod__(...)
 |      x.__rmod__(y) <==> y%x
 |  
 |  __rmul__(...)
 |      x.__rmul__(y) <==> y*x
 |  
 |  __ror__(...)
 |      x.__ror__(y) <==> y|x
 |  
 |  __rpow__(...)
 |      y.__rpow__(x[, z]) <==> pow(x, y[, z])
 |  
 |  __rrshift__(...)
 |      x.__rrshift__(y) <==> y>>x
 |  
 |  __rshift__(...)
 |      x.__rshift__(y) <==> x>>y
 |  
 |  __rsub__(...)
 |      x.__rsub__(y) <==> y-x
 |  
 |  __rtruediv__(...)
 |      x.__rtruediv__(y) <==> y/x
 |  
 |  __rxor__(...)
 |      x.__rxor__(y) <==> y^x
 |  
 |  __str__(...)
 |      x.__str__() <==> str(x)
 |  
 |  __sub__(...)
 |      x.__sub__(y) <==> x-y
 |  
 |  __truediv__(...)
 |      x.__truediv__(y) <==> x/y
 |  
 |  __xor__(...)
 |      x.__xor__(y) <==> x^y
 |  
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |  
 |  __new__ = <built-in method __new__ of type object>
 |      T.__new__(S, ...) -> a new object with type S, a subtype of T

なるほど。勉強になった。やたら、「__」が目立つけど、演算子がメソッドとして実装されているのね。 いつのまにか。ソースではどこに対応するんだろう。 ただ、他にはまったくメソッドが定義されていないので、 事実上「インスタンス」としては使えないなあ。 今まで通りの「オブジェクト」とさして変わりはないような気がする。

ま、少なくとも

  • 確かにPythonでも「すべてはオブジェクト(Smalltalk的な意味でも)」になった(2.2.から?)。 Pythonエバンジェリストの彼はその点で正しい。

ということは明らかになったわけだ。件のページは修正するか。

分かったこと。私はやっぱりPythonに向いてない。 いや、Pythonがわるいってわけではなく、ただ私の脳があまりにもRubyに染まり過ぎているということなのだが(当たり前か)。

ちなみに、上記と同じことをRubyで調べようと思えば

% irb
irb(main):001:0> 1.methods
=> ["%", "between?", "send", ...略...]
irb(main):002:0> 1.class.instance_methods
=> ["%", "between?", "send", ...略...]
irb(main):003:0> Fixnum.instance_methods
=> ["%", "between?", "send", ...略...]

などの方法で直接的に調べられるし、あるいはriを使って

% ri Fixnum
------------------------------------------------ Class: Fixnum < Integer
     A +Fixnum+ holds +Integer+ values that can be represented in a
     native machine word (minus 1 bit). If any operation on a +Fixnum+
     exceeds this range, the value is automatically converted to a
     +Bignum+.

     +Fixnum+ objects have immediate value. This means that when they
     are assigned or passed as parameters, the actual object is passed,
     rather than a reference to that object. Assignment does not alias
     +Fixnum+ objects. There is effectively only one +Fixnum+ object
     instance for any given integer value, so, for example, you cannot
     add a singleton method to a +Fixnum+.

------------------------------------------------------------------------

Includes:
---------
     Precision(prec, prec_f, prec_i)

Class methods:
--------------
     induced_from

Instance methods:
-----------------
     %, &, *, **, +, -, -@, /, <, <<, <=, <=>, ==, >, >=, >>, [], ^,
     abs, div, divmod, id2name, modulo, quo, size, to_f, to_s, to_sym,
     zero?, |, ~

としてもよい。

_ 10代男の子の『なりたい職業』第1位は、プログラマー

なんと。しかし、母集団が男子200名しかないので、1位でも8人。 ほんとに意味があるのか。統計学的にはどんなもんなんでしょう。


«前の日記(2005年01月13日) 最新 次の日記(2005年01月15日)» 編集