プログラミングは素晴らしい

2012-07-16 [プログラミング] Ruby の Ubuntu 12.4 へのインストール

[] RubyUbuntu 12.4 へのインストール 09:07

Virtual Box に Ubuntu 12.4 を入れて、それに rbenv で各種Rubyインストールしたので、その方法のメモ。


sudo aptitude install libssl-dev libyaml-dev libreadline-dev zlib1g-dev
sudo aptitude install libncurses5-dev libgdbm-dev tk-dev

# for maglev
sudo aptitude install build-essential

# for java
sudo aptitude install openjdk-7-jre-headless openjdk-7-jdk

# for git
sudo aptitude install git-all

# for rbenv
sudo aptitude install rbenv

# for ruby-build
cd
git clone git://github.com/sstephenson/ruby-build.git
cd ruby-build
./install.sh

# install all rubies
ls -1 /usr/local/share/ruby-build/ | xargs -idir basename dir| xargs -iversion rbenv install version
rbenv versions
# 以下、出力結果
  1.8.7-p352
  1.8.7-p357
  1.8.7-p358
  1.8.7-p370
  1.9.1-p378
  1.9.2-p180
  1.9.2-p290
  1.9.2-p318
  1.9.2-p320
  1.9.3-dev
  1.9.3-p0
  1.9.3-p125
  1.9.3-p194
  1.9.3-preview1
  1.9.3-rc1
  2.0.0-dev
  jruby-1.6.3
  jruby-1.6.4
  jruby-1.6.5
  jruby-1.6.5.1
  jruby-1.6.6
  jruby-1.6.7
  jruby-1.6.7.2
  maglev-1.0.0

2011-10-14 [プログラミング] Google の新言語 Dart

Google の新言語 Dart でいろいろ遊んでみた。

予約語のように思えた abstractclass、static 、 final 、 get なんかが予約語じゃなくてびっくりした。JavaScript からのポーティングを容易にするためなんだって!本気で JavaScript の置き換え目指しているんだな。

ちょっと勉強しただけだけど下記のような点が印象に残った。

 ・ 演算子オーバーロードがある

 ・ Generics を使える

 ・ 静的型言語と動的型言語の両方の書き方ができる。

  ・ Dynamic 型とかいいね。

 ・ シングルクオート3つとかダブルクオート3つの複数行文字列がある

 ・ 文字列中に ${任意の式} のように書く String Interpolation が可能

 ・ 数は int 型と double 型

  ・ int は int32_t でも int64_t でもなく任意の長整数を表現可能

 ・ 暗黙の型変換が boolean conversion 以外にない

  ・ JavaScript とは違う

 ・ 単に int i と書いた場合は、i は 0 ではなく null

 ・ ちゃんと closure は使える

 ・ static メソッドとか static 変数は override したり hide したりできない

  ・ 継承するクラスは、基底クラスの内部実装も気にせなあかんということなんかな

 ・ 常に単一スレッドで動く

  ・ スレッドの概念がない代わりに isolates という概念がある

  ・ isolates は Erlangプロセスみたいなもの?

ライブラリの方も興味深い。

 ・ 普通に num 型にメソッドがある。Ruby みたいなかんじ

  ・ 100.toRadixString(16) が "64" になるみたいな書き方

 ・ 文字列連結のための StringBuffer 型、immutable な String 型がある

 ・ Queue は Double Ended Queue

  ・ 最初の要素を取り出すのは shift() ではなく removeFirst()

  ・ 最後の要素を取り出すのは pop() ではなく removeLast()

  ・ メソッドオーバーロードで << を再定義したくなるかんじ

 ・ RegExp クラスがある。使い方はめんどそう。

RegExp exp = const RegExp(@"(\w+)");
String str = "Parse my string";
Iterable<Match> matches = exp.allMatches(str, exp);

 ・そういや、String クラスが Pattern インタフェースを実装している

  ・ String クラスでも 上の allMatches() メソッドが使えるみたい。

 ・ Collection インタフェースに foreach() メソッドとかがある。

  ・ List クラス、Queue クラス、Set クラスとかで使える

 ・ Promise クラスがある。JSDeferred みたいなかんじ?

 ・ Dispatcher、Isolate 、ReceivePort 、SendPort が面白そう

けど、いろいろやってみたけど私だったら Dart を使わず、Coffee Script を使うかなぁ。

理由は、

 ・ JavaScriptオブジェクトと挙動が全然違う

main(){
  var obj = {};
  obj["attribute"] = 1;
  print(obj["attribute"]); // 正常実行される
  print(obj.attribute); // 失敗する
}

オープンクラスじゃないから既存のクラスにメソッド追加とかはできない

オブジェクトメソッド追加とかもできない

・ "と'の違いじゃなくて、 @ で string interpolation の有無を区別する

main(){
  var world = "World!";
  print("Hello, ${world}"); // Hello, World!
  print(@"Hello, ${world}");  // Hello, ${world}
  print('Hello, ${world}'); // Hello, World!
  print(@'Hello, ${world}');  // Hello, ${world}
}

 ・メタプログラミング的なことができない

  ・ せめて、typeof くらいは欲しいんだけど・・・。

  ・ for(var i in obj) でオブジェクトの要素を取得することもできない

  ・ foreach はあるけど、Java 的なイテレータのための Syntax sugar

 ・DSL向けじゃない

  ・ CoffeeScript は、() をわりと省略できるのが気に入っていたり。

 ・; を忘れたらバッチリ怒られる。

  ・ めんどい

全体的に、一人で JavaScript を書く程度のレベルであれば発生しないようなコーディング規約とか、他人のソースコードを読めない的な問題を解決するために作られた言語という印象。

Java の人は豊富にいるけど、JavaScript の人はあんましいない開発陣でチーム開発する場合とかは向いているのかもしんない。

JavaScript 技術力が高い開発者だったら、JavaScript でできるのに Dart でできないことがいっぱいあることが気になっちゃいそう。

technohippytechnohippy 2011/10/18 10:34 仕様書の77ページによるとclassとfinalは予約語みたいです。
http://www.dartlang.org/docs/spec/dartLangSpec.pdf

2011-05-22 [プログラミング] メタプログラミングRuby読書会 第2回

[] メタプログラミングRuby読書会 第2回 18:06

3月5日にメタプログラミングRuby読書会を実施しました。

メタプログラミングRuby の中で、カレントクラスという用語が説明されていましたが、

説明が分かりにくいように感じたので新たに整理していこうと思います。

カレントクラスとは、def method_name args ... end のような書き方で、メソッドが定義される場所のことです。

カレントクラスは次のように考えることができます。

- クラスのコンテキストであれば、現在のクラス

- オブジェクトコンテキストであれば、self のオブジェクトの特異クラス

クラスのコンテキストに遷移する方法は次の2通りあり、その場合はそのクラスがカレントクラスになります。

- class または module キーワードでクラス(モジュール)をオープンする

- class_eval でレシーバのクラスをオープンする

逆にオブジェクトコンテキストに遷移するには、instance_eval を使うことになります。この場合はそのオブジェクトの特異クラスがカレントクラスになります

つまり、 instance_eval の中の def はそのオブジェクトの特異メソッド定義になります

クラスのコンテキストへの遷移の中で特に、class <<obj ... end という記法があります。そのオブジェクトの特異クラスを開くときに使う特別な記法です。

このような説明よりも、下記のようなソースを見るとわかりやすいかもしれません。

# (1) トップレベルのメソッド定義( Object に定義される)
def toplevel_method
end

# (2) クラスのコンテキストでのメソッド定義
#     クラスA のインスタンスメソッドとして定義される
class A 
  def instance_method1
  end
end

# (3) class_eval を利用してクラスのコンテキストメソッド定義
#     クラスA のインスタンスメソッドとして定義される
A.class_eval do
  def instance_method2
  end
end

# (4) 特異クラスのコンテキストで実行するための記法 <<obj を利用
#     オブジェクトA の特異クラスをオープンしている。
#     クラスであるオブジェクトA の特異クラスにメソッドを定義している。
#     Ruby では特異クラスのメソッド = 特異メソッドで、
#     クラスの特異メソッド = クラスメソッドなのでこれはクラスメソッドになる
class <<A
  def class_method2
  end
end

# (5) instance_eval の中でメソッド定義
#     instance_eval の中で def ... end を書くと、レシーバ
#     オブジェクトの特異クラスにメソッド定義される
#     A はクラスなので、これはクラスメソッドになる
A.instance_eval do
  def class_method1
  end
end



class A
  def initialize
    # (6) 通常のインスタンスメソッドの定義
    # クラスのコンテキストなので、インスタンスメソッドが定義される
    def instance_method3
    end

    # (7) クラスのコンテキストから、instance_eval を実行して特異メソッドを定義
    # オブジェクトの特異クラスにメソッドが定義されるため、
    # シングルトンメソッドが定義される
    self.instance_eval do
      def singleton_method1
      end
    end
  end
end


# (8) トップレベルから instance_eval で特異クラスにメソッドを定義
a = A.new
a.instance_eval do
  def singleton_method2
  end
end

# (9) オブジェクトを指定したメソッド定義
#     指定したオブジエクトの特異クラスにメソッド定義される
#     特異メソッド定義中でもカレントクラスは変更されないため、
#     トップレベルのメソツドになる。
def a.singleton_method3
  def toplevel_method2
  end
end

a.singleton_method3

p a.singleton_methods
p A.instance_methods - methods
p A.singleton_methods

2010-07-04 [プログラミング] LiveCoding で 解説

[] LiveCoding で 解説 18:09

cuzic です。

もう先週のことですが、LiveCoding#10 に参加してきたら、突然 解説を依頼され、解説してきました。

イベント内容は、yhara さんと nari さんのすごいギークコーディングするのをみんなで見よう!みたいなもので、最近は sixeight さんが中心に非常に熱気を持って実施されています。

LiveCoding#10 では「プロの変な言語作者」yhara さんと、「日本のガーベッジコレクション界の権威」 nari さんが最強タッグを組んで、新しい言語をわずか40分で実装するというものでした。

yhara さんの整数文字列を含めてすべてを配列で表現するという新言語にはちょっとドギモを抜かれました。

変な言語にはいろいろとありますが、そこまで限定をするという発想にはびっくりしました。

40分時間があるとはいえ、ちゃんとテストを書きながらコードを書いていた点も感銘を受けました。自分のスタイルへのこだわりを感じます。

ガーベージコレクションについては基本的な原理などは一通り勉強したことはあるものの、実際のコードについては、ちゃんと見て勉強したことなどはあまりなかったので、今回の企画のようにコンパクトなガーベッジコレクション実装を実際に作成しているところを見ることができたのは、大変勉強になりました。

私の解説についてですが、突然の依頼で準備が足りず、聞き苦しかった部分もあったかと思うのですが、多くの方から好評いただいていたようで、よかったです。

SixeightSixeight 2010/07/09 03:03 突然のお願いだったのに快く引き受けてくださってありがとうございました!

2010-06-22 [プログラミング] Ruby でクラス定義の DSL 作成

[] Ruby でクラス定義の DSL 作成 00:32

cuzic です。

今日も Ruby の話題です。

理由はないのですが、大林さんの昔出した課題のような問題に取り組んでみました。

目標は、

  A = AttrClass :accessor, :with_default => 1 do
    def initialize
      puts "initialized"
    end

    def do_something
      puts "do_something"
    end
  end
  a = A.new #=> intialized
  p a.accessor #=> nil
  a.accessor = "some value"
  p a.accessor #=> "some value"
  p a.with_default #=> 1
  a.with_default = 2
  p a.with_default #=> 2
  a.do_something #=> do_something

となるような AttrClass メソッドを定義することです。

つまり、AttrClass メソッドの呼び出しが下記のコードと等価になるようにする、ということです。

 class A
   attr_accessor :accessor
   attr_accessor :with_default 
   def initialize
     @with_default = 1
     puts "initialized"
   end

   def do_something
     puts "do_something"
   end
 end

これはやってみると、比較的簡単にできました。

次のようなメソッド定義になります。

def AttrClass *symbols, &block
  Class.new do |klass|
    symbols.each do |sym|
      case sym
      when Symbol
        attr_accessor sym
      when Hash
        klass.class_eval do
          sym.each do |key, value|
            attr_accessor key
          end
        end
        Module.new do
          new_original = klass.method :new
          define_method :new do |*args, &block|
            obj = new_original.call *args, &block
            sym.each do |key, value|
              obj.__send__ "#{key}=", value
            end
            obj
          end
          extend_object klass
        end
      end
    end
    klass.class_eval &block
    klass
  end
end

ポイントは、Class#class_eval を使って、Classコンテキストでブロックを評価していることや、new クラスメソツドを再定義して、インスタンス変数初期化を行っているところでしょうか。

これを使えば、アクセサなどが多いクラス定義がより簡潔に書けます。

okkezokkez 2010/06/23 01:35 二番目のコード例がなんかおかしい気がする。SyntaxError

cuziccuzic 2010/06/23 06:55 コピペのときに、ゴミがついていました。
ご指摘ありがとうございます。
修正しました。