就職まで少し時間が空く

もう少しで時間が空くので,新たな言語でも使ってみようかということで思案中.
今のところの候補はhaskellscalaあたり.
関数型言語の方に興味が惹かれる.
もしくは並列化が容易な言語.
ちくちくとproject Eulerでもやりつつ,rubyでtddも同時並行でやってみようかという感じ.

おすすめはなんだろ.

いまさらRubyでMapReduce

以下の記事を見つけていまさら書いてみた.
http://romeda.org/blog/2007/04/mapreduce-in-36-lines-of-ruby.html
Hadoopとかいろいろあるけどさ.

実行環境

正確かな?
OS: VMWare上のCentOS
Ruby: 1.9.1

% uname -a
Linux localhost.localdomain 2.6.18-128.1.6.el5 #1 SMP Wed Apr 1 09:19:18 EDT 2009 i686 i686 i386 GNU/Linux
% ruby -v
ruby 1.9.1p0 (2009-01-30 revision 21907) [i686-linux]

必要なgem?

RingyDingy

% sudo gem install RingyDingy

他にもいるのかもしれないけど.

実行例

サーバ側
% ring_server &

% ruby mapreduce_runner.rb &

% ruby mapreduce_runner.rb &

とりあえず2つ起動させた

クライアント側
% irb -r mapreduce_enumerator.rb
irb(main):001:0> (0..10).to_a.mapreduce(->(x){x*2}, 0, ->(sum,x){sum+=x})
=> 110

引数として(map用Proc,reduce初期値,reduce用Proc)を渡す.
blockを複数渡すにはどうすればいいの?

コード

mapreduce_runner.rb
require 'rubygems'
require 'ringy_dingy'

ringy_dingy = RingyDingy.new nil
ring_server = ringy_dingy.ring_server

loop do
  identifier, pid, block, element, idx = ring_server.take([nil, nil, nil, nil, nil])
  begin
    result = block.call(element)
  rescue Object => err
    result = err
  end
  puts "Got #{result.inspect} from #{element} for pid:#{pid}."
  ring_server.write([identifier, pid, result, idx])
end
mapreduce_enumerator.rb
require 'rubygems'
require 'ringy_dingy'

module Enumerable
  def dmap(&block)
    self.each_with_index do |element,idx|
      ring_server.write([:dmap, Process.pid, block, element, idx])
    end

    results = []
    self.size.times do
      result, idx = ring_server.take([:dmap, Process.pid, nil, nil]).last(2)
      results[idx] = result
    end

    results
  end

  def mapreduce(map_proc, initial_value, reduce_proc)
    self.each_with_index do |element,idx|
      ring_server.write([:mapreduce, Process.pid, map_proc, element, idx])
    end

    results = initial_value
    self.size.times do
      result, idx = ring_server.take([:mapreduce, Process.pid, nil, nil]).last(2)
      results = reduce_proc.call(results, result)
    end
    return results
  end

  def ring_server
    return @ring_server if @ring_server

    ringy_dingy = RingyDingy.new nil
    @ring_server = ringy_dingy.ring_server
  end
end

戯言

実行するmapreduce毎にユニークな識別子を指定しないと結果が混ざりそうです.

企業説明会が時計台でありました

うちの研究科主催なんで,DEIMに投稿する論文修正待ちの間に行ってきた
内部の説明会なんで,もちろん私服でいきましたとも

そしたら異世界
スーツががががが

とまぁ出鼻をくじかれましたが,とりあえずKDDIにOcupさんがいたので挨拶がてら話しました

次いでお目当ての某社に行きました

(中略)

Tシャツもらいました

べ,別に説明会でID書いたから日記書いたわけじゃないんだからね><

相手がほしいものがわかる7つの方法

そんなものがあれば教えてください
以下は方法まとめてみた雑記

店の人が勧めるままに選ぶ

プロに任せてみます
プロの選び方次第かと…
案外失敗率高そう(個人的感想)

察する

そんなことができれば苦労はしません

定番・無難なものを選ぶ

匿名相談もここに入るんでしょうか
季節モノとかの定番品はハズレることは少ないと思います
たぶん一番利用する方法です

人づてに聞いてみる

ニヤニヤされるので気が引けますが…
イロイロとめんどいです

直接聞いてみる

「なんでもいいよー」という悪魔の言葉が返ってくると思いますが,ハズレはなくなります
サプライズ感もなくなるけどね

一緒に買いに行く

いっそのことならば!
あまり金額を感じさせたくないならば上の方法かな?

以前の会話(や記述)を覚えておく

理想的ですが,そんな甲斐性さえがあれば…
記憶力かメモ力が勝負の鍵

おまけ

感覚で買って成功するなら苦労はしないのさ

Pandocって何?

ここ↓を参照すればわかるけども,テキスト形式を色々と変換してくれるtoolなのです.
Markdown/HTML/LaTexを相互変換·Pandoc MOONGIFT

苦労したそもそもの原因

仕様要求ではghc6.8以上なんですが,ubuntuのapt-getで持ってこれるのが6.6系だってこと.

と,いうわけで

ここ↓を見ながらソース引っ張ってきてコンパイル→インストール
http://www.gabuchan.net/blog/archives/32
コンパイルの途中で

No space left on device

と散々エラーをはいてくれる.
仕方がないので,救済措置で

env TMPDIR=&HOME [command]

としてtmpを仮割り当てしながら進めていく.
んで,あとは必要なlibを順番に突っ込んでいく

wget [lib url]
tar xvf [lib file]
cd [lib folder]
runhaskell Setup configure
runhaskell Setup build
sudo runhaskell Setup install

とにかくめんどい
なぜHaskellなのか?
これだけのためにHaskellをインストールする自分が悪いんでしょうか?
とりあえず入れたところまで

gemが通らない

さくっと入れている人たちはこれくらいできるのであろうか
状況はこちら↓
http://rubyforge.org/forum/forum.php?thread_id=26771&forum_id=15560
まずは(落としてきた)gemを展開

sudo gem unpack igraph

上記リンクのように修正

Index: cIGraph_file.c
===================================================================
--- cIGraph_file.c (revision 70)
+++ cIGraph_file.c (working copy)
@@ -502,6 +502,9 @@
igraph_integer_t target;
igraph_vector_t capacity;

+ igraph_strvector_t problem;
+ igraph_vector_t label;
+
igraph_t *graph;
igraph_bool_t directed_b = 0;

@@ -525,9 +528,9 @@
string = rb_funcall(file, rb_intern("read"), 0);
stream = fmemopen(RSTRING(string)->ptr,RSTRING(string)->len, "r");

- igraph_read_graph_dimacs(graph, stream, &source, &target, &capacity, directed_b);
+ igraph_read_graph_dimacs(graph, stream, &problem, &label, &source, &target, &capacity, directed_b);

- fclose(stream);
+ close(stream);

igraph_vs_all(&vs);
igraph_vit_create(graph, vs, &vit);

ここからがわかんなかった

疑問:展開して改変したのってどうinstallすればよいのか
解答:もう一度gem化してしまう

どうすれば?

見てみると.gemspecを書いてgem buildしろとか書かれてるけども
そんなファイルなんてない
HoeをRakefile.rb内で呼び出してるのはなんでかな?
と思いググると…
これでした!
でもそもそもrakeが通らない…
内部でigraphを呼んでるのが原因っぽいのでとりあえずコメントアウト

Index: Rakefile.rb
===================================================================
--- Rakefile.rb	(revision 70)
+++ Rakefile.rb	(working copy)
@@ -7,7 +7,7 @@
 end
 
 begin 
-  require 'igraph'
+#  require 'igraph'
 rescue RuntimeError
 end

これで通りました
rubigraphに関してはまたそのうちにでも