K.Sasada's Home Page

Diary - 2005 September

研究日記

長月

_30(Fri)

るびまのプレゼントは今日までですが、なんか駆け込みな感じ。


pthread べったりだが、スレッドできた。入出力まわりはまだ。


今度から --enable-pthread を付けないとコンパイルできなくなりました。

In YARV HEAD version, --enable-pthread option is required.


pthread 無し、というのは今の Ruby ですが、あれをまた持ってこれるだろうか。なんか色々やってるんだよなぁ。

ちなみに、対応したのはもちろん giant lock なやつです。

_babie(Fri Sep 30 15:17:55 JST 2005)

 もっと駆け込んで欲しいですね。

_29(Thu)

coLinux、なかなか使えそう。

  • インストール
  • apt-get で色々入れる
  • 1GB だとそろそろ小さい
  • 8GB の raw file を用意
  • とりあえずデバイスとして認識させる(xml を書き換えるだけ)
  • 1GB を dd if=... of=... で単純にコピー
    • この時点で 8GB のデバイスに 1GB の領域ができる
  • GNU parted で 8GB に伸張。なんか partition を 8GB として認識してたんだけど、まぁいいか、えいやってことで引きなおし。するとなんか沢山警告が出てきたんだけど、マウントしてみたら 8GB になっていた(df で確認)ので、よかったよかった。
  • 開発するソースをどっちに置くか、ということで、とりあえず smbmount で Windows(ホスト)側のものをマウントして、ビルドは coLinux としてみる。

おお、動いた。


function_call_may_return_twice_false の意味がよくわからないなぁ。


smbmount したら、変なタイミングで勝手に touch されてる気がする(xyzzy で「誰かが勝手に変更した」、と出る)。なぜだ? なんか gcc でコンパイルするとなってるみたいなんだが。なぜだろう。

ro で mount しても同様。はて、samba の仕様だろうか。日付関係をいじってるんだろうか。


define よりは declare のほうがなんかそれっぽいなぁ。

register のほうがいいか。option register zoo で orz{ ... } なんてのはどうでしょうか>OptionParser。z が思いつかなかった orz


kernel update したら、bcm5700.o を再インストールする羽目になった。動かない、動かない。bcm5700.o を入れなおしても動かない。ぐぐりまくって http://lists.debian.org/debian-user/2005/05/msg01271.html を見て、tg3 で work fine.

一時間つぶした。

kernel の update なんてするもんじゃないなぁ。

_28(Wed)

cygwin の pthread_kill がうまく動いてくれないのではまり中。


#include "pthread.h"
#include <signal.h>

#define SIG SIGVTALRM
//#define SIG SIGTERM

pthread_t maint, timert, ct;
volatile int flag;

void *timer_func(void *p){
  sigset_t mask;
  sigemptyset(&mask);
  sigaddset(&mask, SIG);
  //pthread_sigmask(SIG_BLOCK, &mask, 0);
  
  while(1){
    sleep(1);
    if(pthread_kill(maint, SIG) != 0){
      printf("failed\n");
      exit(0);
    }
  }
  return 0;
}

void catch_timer(){
  ct = pthread_self();
  flag = 1;
  
}

int main(){
  unsigned int i = 0;
  {
    struct sigaction sigact, old;
    sigact.sa_handler = catch_timer;
    sigemptyset(&sigact.sa_mask);
    sigact.sa_flags = 0;
    sigaction(SIG, &sigact, &old);
  }

  maint = pthread_self();
  if(pthread_create(&timert, 0, timer_func, 0) == 0){
    
  }
  printf("maint:  %p\n", maint);
  printf("timert: %p\n", timert);
  
  while(1){
    if(flag == 1){
      flag = 0;
      printf("hoge, %p\n", ct);
    }
    // printf("%d", i++ % 7);
  }
  
  return 0;
}

実行すると SEGV する。なぜ...。

printf("hoge"); を消すと動くな。なんかコンテキストが戻ってないのか?


cygwin が悪いのか、俺の使い方が悪いのか。

gauche は(もっというと、その中の BoehmGC は)pthread_kill できちんと stop world GC をやってるんだよねぇ。


なんか、2度目以降の sleep(1) が聞かない(待たない)らしい。


なんか、2度目以降の pthread_kill が効かないらしい。なぜだろう。マスクしているわけではないんだけど。

シグナルマスク以外でシグナルを止める要因ってなんかあったっけ。


16 4558903 [sig] a 1808 setup_handler: trying to send sig 30 but signal 30 already armed

こんな出力が。



#include <pthread.h>
#include <signal.h>

#define SIG SIGUSR1
//#define SIG SIGTERM

pthread_t maint, timert, ct;
volatile int flag;
int cc;
sigset_t mask;

void sleep_func(int sec){
  clock_t fin = clock() + sec * CLOCKS_PER_SEC;
  while(1){
    if(clock() > fin){
      break;
    }
  }
}

void *timer_func(void *p){
  int i;
  for(i=0; i<3000; i++){
    sleep_func(1);
    printf("timer: %d, cc: %d\n", i, cc);
    if(pthread_kill(maint, SIG) != 0){
      printf("failed\n");
      exit(0);
    }
    // break;
  }
  return 0;
}

void catch_timer(int sig){
  cc++;
  ct = pthread_self();
  flag = 1;
}

void *func(void *p){
  unsigned int i = 0;
  struct sigaction sigact;
  sigact.sa_handler = catch_timer;
  sigemptyset(&sigact.sa_mask);
  sigact.sa_flags = 0;
  sigaction(SIG, &sigact, 0);

  maint = pthread_self();
  if(pthread_create(&timert, 0, timer_func, 0) == 0){

  }
  printf("maint:  %p\n", maint);
  printf("timert: %p\n", timert);

  while(1){
    if(flag == 1){
      flag = 0;
    }
  }
  return 0;
}

int main(){
  pthread_t th;
  pthread_create(&th, 0, func, 0);
  pthread_join(th, 0);
  return 0;
}

結局動かなかった。どうしよう。


お手上げ。

_tls->sig を 0 clear してないからいけないんだけど、cygwin のソースを読んだらしているように見える。

やはり不思議なのは、BoehmGC がきちんと動いていることだ。


と、思ったら Gauche も死んでるなあ。

(define store #f)

(use gauche.threads)
(define (m)
        (thread-yield!)
        #?=(current-thread)
        (set! store (cons 1 2))
        (m))

(thread-start! (make-thread
                (lambda () (m))))

(m)

#?=(current-thread) これを入れたらちゃんと死ぬようになった。cons だけではヒープを圧縮しないのかしらん。

cons cell は別管理ってことなのかなぁ。


まぁ、とりあえずこれを回避する魔法は無いことはわかったのでこれでいいや。午前が丸々潰れてしまった。


発端は eval.c の thread_timer で pthread_kill をしていることなんだけど、これ本当に要るのかなぁ、と思ったら EINTR を投げるために必要ってシナリオなんですね。

となると、これが使えない cygwin ではそもそも enable-pthread が無理ってことなんですね。

EINTR で無理やり終わらせる必要がある操作って何があるんだろ。


flock, waitpid とかか。



#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>


void *wait_func(void *p){
  pid_t pid;
  int st;
  if((pid = fork()) != 0){
    if(waitpid(pid, &st, 0) < 0){
      switch(errno){
      case 0:
        printf("0 orz\n");
        break;
      case EINTR:
        printf("success!\n");
        break;
      default:
        printf("other: %d orz\n", errno);
        break;
      }
    }
    exit(0);
  }
  else{
    // child
    while(1){
    }
  }
  return 0;
}

void handler(int sig){
  /* do nothing */
}

int main(){
  pthread_t th;
  struct sigaction sigact;
  
  sigact.sa_handler = handler;
  sigemptyset(&sigact.sa_mask);
  sigact.sa_flags = 0;
  sigaction(SIGUSR1, &sigact, 0);

  pthread_create(&th, 0, wait_func, 0);
  sleep(2);
  pthread_kill(pthread_self(), SIGUSR1);
  sleep(10);
  return 0;
}

cygwin での結論。

  • pthread_kill を自スレッド以外にかけると、その相手に二度と pthread_kill はできない
  • pthread_kill を自スレッドにかけても問題ない
  • pthread_kill を自スレッドにかけると、他のスレッドの待ちが開放される(EINTR が発生する)

というわけで、eval.c の中は、cygwin なら自スレッドに pthread_kill すれば良さそう。


こんなときに体の調子は激しく悪い。ああ、VM の講演聴きたかった。


嘘だった。複数待っているスレッドを作っても、ひとつしか EINTR にならなかった。

ちょっと考えてみたけど、複数のスレッドを起こす方法がわからない。cygwin で pthread プログラミングは無理ってことか?

#include <pthread.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>


void *wait_func(void *p){
  pid_t pid;
  int st;
  if((pid = fork()) != 0){
    printf("create: %d\n", pid);
    if(waitpid(pid, &st, 0) < 0){
      printf("awake: %d\n", pid);
      switch(errno){
      case EINTR:
        printf("success!\n");
        break;
      default:
        printf("other: %d orz\n", errno);
        break;
      }
    }
    kill(pid, SIGKILL);
  }
  else{
    // child
    while(1){
    }
  }
  return 0;
}

void handler(int sig){
  /* do nothing */
}

int main(){
  pthread_t th1, th2;
  struct sigaction sigact;
  
  sigact.sa_handler = handler;
  sigemptyset(&sigact.sa_mask);
  sigact.sa_flags = 0;
  sigaction(SIGUSR1, &sigact, 0);

  pthread_create(&th1, 0, wait_func, 0);
  pthread_create(&th2, 0, wait_func, 0);
  sleep(1);
  if(0 /* Linux */){
    pthread_kill(th1, SIGUSR1);
    pthread_kill(th2, SIGUSR1);
  }
  else{
    /* cygwin */
    // いろいろやってみたけど無理だった
    pthread_kill(th2, SIGUSR1);
    // たとえば、このプログラムでは、th1 の待ちを解除する orz
  }
  sleep(10);
  printf("application close");
  return 0;
}

cygwin で pthread が駄目ってことで、VMWare か VirtualPC を買おうと思うんだけど、どっちがいいかな。


とりあえず coLinux を入れてみたが、coLinux 側からネットワークをつなぐのはどうするのがいいんだろう。


おお、動いてるようだ。

_さかい(Wed Sep 28 20:47:49 JST 2005)

 colinuxでいいじゃん

_ささだ(Wed Sep 28 21:12:29 JST 2005)

 なんかねー、coLinux の良くない話を聞いて。とりあえず coLinux で実験だけしてみるかな?

_Luis(Sun Jun 24 01:29:49 JST 2007)

Hello, I am from Mexico, I think that is very good that you write tutorials in your language.

_shiro(Sun Jun 24 05:24:15 JST 2007)

 あれ、Boehm GCはcygwinの時でもWin32 Threadsを使ってるんじゃなかったかな…

_27(Tue)

caller の self や binding が欲しい、という話があるのだけれど、それに依存しだすと delegator や dRuby なんかで大変なことになりそう。


なんとなく、local_variables に対応。なんか、ブロックを辿るのが苦手だな。


rb_backref_set とかを鬱陶しいから parse.y から駆逐。


TOPLEVEL_BINDING を作るのは実は容易ではないことに気づいた。無しにしよう、無しに。

・・・というわけにはいかないんだろうなぁ、きっと。

具体的には

a = 1
eval('p a', TOPLEVEL_BINDING)

こんなのが難しい。

あれ、require された側で TOPLEVEL_BINDING を参照したら動かないな。なんでだろう。

_26(Mon)

binding が出来たような、出来てないような。


昼休みに学校のネットワークが止まることが多いような気がする。


さて、後はローカル変数の話だけなんだが...。


また、ruby-dev に投げようと思って、どうしようか迷っているネタ。

 ささだです。

 eval の中で新しい変数を宣言したとき、それはブロックローカル
変数相当になると思うのですが、defined? は "local-variable" を
返します。

eval %q{
  a = 1
  p defined? a #=> "local-variable"
  1.times{
    b = 2
    p defined? b #=> "local-variable(in-block)"
  }
}
p a
#=> undefined local variable or method `a' for main:Object (NameError)

 こういうものでしょうか。

-- 
SASADA Koichi at atdot dot net

どーでもいいぢゃん。

いや、yarv でテストに失敗して(yarvでは in-block が返る)。どうしようかな。


yarv のテストは eval でやってるんだけど、困った。


in block になっちゃうのは私の実装のやり方の問題なのですが、これが許されないと、いろいろと大変。でも、きっとどっちでもいいに違いない。

_なかだ(Mon Sep 26 15:44:47 JST 2005)

 ブロックの中じゃないじゃん

_ささだ(Mon Sep 26 18:25:01 JST 2005)

 ブロックじゃないですが、さりとてローカル変数として eval の外で使えるわけでもないので。

_25(Sun)

偉い人は大変だ。


「Ruby」においてセーフレベル4がサンドボックスとして機能しない脆弱性 を見て、$SAFE=4 をサンドボックスとして使うのか、と思ったのが発端。

不特定多数に公開するような運用は、(多分誰もやらないだろうけれど)危険だよねぇ。多分。


parse.y のパッチは結局取り込まれない & ruby_scope などの影響を取り除くため、もう parse.y も独自路線で行くことにした。パーサの変更に追いつこうとすると大変だなぁ。


早速 parse.y の修正があったのでパッチを取り込もうと思って、手でパッチファイルを修正したら、malformed patch になってしまった。しくしく。こういう場合はどうしたもんなのかな。


なんとかした。


喫茶店を探して旅に。何軒かいって、やっと腰を落ち着けたと思ったら赤ん坊連れの方がいらして大変な騒ぎに orz


binding が出来ないんだよなあ。どうしよ。

YARV では、Binding ではなくて Env オブジェクトというのをそれの代わりにしようと思っているのだけれど、本当にこいつだけで出来るのか不明。


Env はローカル変数などを記憶しているんだけど、

def m
  i = 1
  binding
end

eval('p i', m)

とやった場合、'p i' のパースの時点で m の中の「ローカル変数一覧」を覚えておいて、パース時にこれを利用する必要がある。

Env と「ローカル変数一覧」はあんまり、というか全然関係ないので困る。どうしよう。iseq を憶えていないといけない、ってことか。

Env が iseq を持つって、直感的じゃないよな。でもまぁ、しょうがないか。


def m
  a = 1
  1.times{|e|
    binding
  }
end

eval('p [a, e]', m)

みたいなのを考えると、余計に。でも、逆に言うと保存すれば出来るので問題ない、かも。


う、またなんか言われそう。


eval をするときには、そもそもそのときの Env を渡さないといけないんだよな。なんかとても不合理な気がする。どうしたもんだか。

呼び出し側の iseq さえあれば問題ないのか?

_まつもと(Mon Sep 26 08:48:46 JST 2005)

parse.yにパッチを当てる件は1.8のリリースで忙しくて放置してました。 当てても構いませんけど、今後のことも考えると自分でパッチを当ててほしいなあ。

_ささだ(Mon Sep 26 11:45:14 JST 2005)

 はい。お忙しいのは重々。ということで、自分でパッチをあてることにしました。文法の変更はガンガンありそうですかねぇ。ガクガクブルブル。

_まつもと(Mon Sep 26 23:15:17 JST 2005)

 ちゅーか、本家のCVSにコミットしてほしい

_ささだ(Tue Sep 27 23:29:00 JST 2005)

 実は、もう切り離すと割り切ってparse.yに色々手を入れてしまいました。まぁ、今の状態だったら巻き戻しもそんなに辛くないかも。

_24(Sat)

問題視していたことがあんまり問題じゃなかったことが判明。とりあえず、リファレンスマニュアルに追記してもらおう。


Rubyリファレンスマニュアル - セキュリティモデル

レベル4は信頼できないプログラムによる危険な操作をほぼ全て検出できますが、完全な安全性は保証されません。

もう書いてあるじゃん。しかし、この記述も微妙かも。この後で、

このレベルではレベル3では禁止されている「汚染された文字列のeval」が許可されています。(evalで実行すると危険な操作は全て禁止されているからです。)

全てじゃない、って上で書いてあって、下では「全て」と書いてある。

DoS などを防ぐには、このページに書いてある例では不完全で、別プロセスにしないと完全じゃないっぽい。

書き途中だった ruby-dev への手紙。

 ささだです。

 $SAFE = 4 は本当にサンドボックスの用を足すのか、という話ですが、
同じプロセスで走らせていると DoS のようなことが容易に出来そうです。
security@ ではなく、ruby-dev 向け、ということなので、こちらに投稿
します。


require 'timeout'

def st script_in_sandbox # sandbox test
  out = lambda{|e|
    p e
  }

  begin
    p Thread.new{
      Thread.current.priority = 10000
      $SAFE = 4
      timeout(1){
        eval script_in_sandbox
      }
    }.value
  rescue SecurityError => e
    p :SecurityError
    p e
  rescue Exception => e
    p :Exception
    p e
  end
  p :finish
end

 このようなスクリプトを用意して、いくつか試しました
(ruby 1.9.0 (2005-09-23) [i386-cygwin])。

・命令流関係

st %q{
  set_trace_func{
    sleep 1
  }
}

 1.9.0 だと、アプリケーションが落ちました(何も言わずに exit)。
1.8.2 だと、set_trace_func が利きました。


・メモリを食いまくる

st %q{
  i=0
  loop{
    i+=1
    "sym#{i}".to_sym
  }
}

 シンボルは GC によって開放されないため、sandbox から抜けてもメモリ
を消費したままになっています。


loop{
  GC.start
st %q{
  pr = lambda{pr.call}
  msg = nil
  begin
    pr.call
  rescue SystemStackError => e
    str = 'a'*(1024 * 1000)
    e.message << str.dup
  end
}
}

 これも同様です。ちなみに、これもアプリケーションが落ちました(1.9.0)。



 多分、他にもあると思うのですが、こういうことは、sandbox としては好ま
しくないと思います。たとえば、常駐型のプロセスによるサービス上でこの機
能を利用して sandbox として提供した場合、意図せずにサービスを中断する
ことが可能です。

 これを防ぐには、子プロセスを起動して、その上で $SAFE=4 で動かして、
親プロセスは時間切れなら kill する、というような方法が考えられるそうです。

 そのあたりのことが

Rubyリファレンスマニュアル - セキュリティモデル
http://www.ruby-lang.org/ja/man/?cmd=view;name=%A5%BB%A5%AD%A5%E5%A5%EA%A5%C6%A5%A3%A5%E2%A5%C7%A5%EB 
に書いておらず、$SAFE=4 では危険なプログラムを動かしても安心、という書き方になっている ...

> レベル4は信頼できないプログラムによる危険な操作をほぼ全て検出できますが、完全な安全性は保証されません。

いつの間にか、完全ではない旨が増えてるんですね orz

 まぁ、「完全な安全性は保障されない」のならば、sandbox 用子プロセス
を立ち上げる方法を紹介するのはいいんじゃないでしょうか。


-- 
SASADA Koichi at atdot dot net

でも、「完全じゃない」ものが $SAFE=4 ならば、別にバグではないので、指摘は見当違いかもしれない。

というわけで、なんか意味がない気がしたので送るのはやめた。


そもそも、

st %q{
  begin
    loop{}
  rescue Exception => e
    out.call(e)
  end
  loop{}
}

こうやって timeouterror を握りつぶしてしまえば timeout はかからないっぽい。

じゃぁ、っということで、

def st script_in_sandbox # sandbox test
  out = lambda{|e|
    p e
  }

  begin
    th = nil
    timeout(2){
      Thread.new{
        th = Thread.current
        Thread.current.priority = 10000
        $SAFE = 4
        timeout(1){
          out.call(:StartSandbox)
          ans = eval script_in_sandbox
          out.call(:FinishSandbox)
          ans
        }
      }.value
    }
  rescue SecurityError => e
    p :SecurityError
    p e
  rescue Exception => e
    th.kill if th && th.alive?
    p :Exception
    p e
  end
  p :finish
end

st %q{
  begin
    loop{}
  rescue Exception => e
    out.call(e)
  end
  loop{}
}

こうやってみたんだけど、うまく timeout してくれない。 なんでだろ。


priority が高かったからだった。フェアネスは?


set_trace_func を実行したらアプリケーションが何を言わずに終了、というのは

set_trace_func lambda{
}

これだけでも再現できた。要するに lamda に渡す引数の数が違うから、と。どっかに例外投げてもらえればよかったんだが。


ということで、$SAFE=4 で set_trace_func が 1.9 でも利くことがわかった。


SICP 中止になってしまった。しょぼん。


rb_thread_t の anchor ってなんだっけ。参照してないっぽいのだけど。callcc のときのだった気がするんだけれども。

スレッドをまたいだりするのがまずいものをはねるんだっけ。あれ、ほんとかな。

_なかだ(Sat Sep 24 20:54:45 JST 2005)

それはcont_protect。 anchorは新しいThreadを作るときに使用するやつだけど、 兼用できるんじゃないかということ?

_ささだ(Sun Sep 25 14:16:35 JST 2005)

 あれ、使ってましたか。何に使うんだろ。

_23(Fri)

ストックが二つしかないのですぐに終わってしまいそうだ。しかしすぐに終わったら目的が達成できないっぽい。


しかし、セキュリティの問題はよくわからんなぁ。何が公開するべきで何を公開しないべきか。公開しないときのリスクは。

任意のコードが実行される可能性がある場合、それは大変なことだけど、たとえば [BUG] を引き起こすコードはどうなんだろう。


今日が祝日だということにさっぱり気づいていなかった。


今結構へこんでるんですが、【一周年記念企画】 Rubyist Magazine へのたより を見て頑張ろう、とか思ってみたり。これは全然読者向けじゃなくて、内部向けだよね。


なんで singleton method は許すんだろう。


HEAD を build、と思ったら ripper を作るときに stringio が無いと言われる。[ruby-dev:27307]。nokada さんはなんでこんなに手が早いんだろう。

というわけで、コミットされるのを待つか。


パッチがすんなりあたったので、あててみた。相変わらず、cygwin 上で test-all では segv する。


eval.c はもう全然変えてしまったのでパッチがあたらない。どうやって ANSI style にしようかな。


parse.y から ruby_scope ステのためのパッチは、やっぱりあたらないだろうか。

もう、覚悟して parse.y も ruby HEAD から切り離すかなぁ。


そういえば、横に伸びるのが嫌だ、といっていたので、

int
func(int a, int b, int c, int d, int e, int f)
{
  ...
}

じゃなくて

int
func(int a,
     int b,
     int c,
     int d,
     int e,
     int f)
{
  ...
}

とするのかと思ったら違うらしい。

しかし、int f の後ろにカンマ入れたいよなあ。


わーい、ためにためていたら diff が 4 万行だ。

主に、殺して解して並べて揃えて晒してみたって感じ。


たださんの日記を見て、自分は5年後を見てるんだろうか、と不安になる。

... ruby2 は 5 年後かも、という落ちか。


.ext/ripper.rb:1:in `require': no such file to
 load -- ripper/core (LoadError)

うなー。


5年後、10年後、20年後、50年後はいつも考えているつもりなのだけれど、今についていくのが精一杯という感じ。


そして cygwin でいつもどおり segv> make check

_maeda(Sat Sep 24 00:56:27 JST 2005)

 ANSI化 -- protizeってもうないの?

_22(Thu)

マシンを変えたとき、pivot をインストールしてなかったんだが、今確認したらグラフィックカードのドライバで回転できるじゃん。


sandbox をテストするスクリプトは作れるだろうか。SecurityError が出るようなスクリプトを大量に用意すればいいのか。めんどくさそう。


Cell のリファレンスボード発売か。


コメント spam は全然来ていない感じ。


t = Thread.new{
  p self # (1) これをはずすと動作が変わる
  t.instance_eval{
    p self # (2)
    initialize{
      p 1
    }
    p 2
  }
}
t.join

最初の (1) p self があったりなかったりすると動作が変わる。(1) をはずすと (2) が nil になってしまう。

理由が全然わかんない。


これから毎日頑張ってみよう(何を)。

_sheepman(Thu Sep 22 23:33:46 JST 2005)

 p self # (1) の時にスレッドが Thread.main へと切り替わって、そこで始めて t に Thread オブジェクトが代入されるからでは。p self # (1) がないとスレッドが切り替わらず t は nil のまま。

_ささだ(Thu Sep 22 23:50:50 JST 2005)

 あー、なるほど。

_21(Wed)

英語でmag-a-zineじゃなくてma-ga-zineだから

RubiMa がいい、とあるネイティブが言ってました。


1.8.3 お疲れ様です。


ICPC のコーチの代理をやることになってしまった。


しかし、safelevel 4 を信頼してサンドボックスに使う人なんているのかな。まぁ、リファレンスマニュアルはそれを推奨するような文面があるようだけれど。

_babie(Wed Sep 21 13:52:39 JST 2005)

 要素で分けるとそうなるのかぁ  と思ったら違った。  http://dic.yahoo.co.jp/bin/dsearch?p=magazine&stype=1&dtype=1  http://dic.yahoo.co.jp/bin/dsearch?p=mag&stype=1&dtype=1

_ささだ(Wed Sep 21 14:33:55 JST 2005)

 わはは。

_20(Tue)

なぜかデビルマンを読む。うわ、黒。


ふと、multi-vm にしたとき、ID の管理はどうするべきかなと考える。あるひとつの VM インスタンスが ID を大量に作成しても、それを回収する手段が無いのだよな。でも、たいていの場合は共有するだろう。

デザインとして、どっちに振るべきなんだろうなあ。


うーん、難しいはずないんだけどなぁ。おかしいなあ。

_19(Mon)

ある高校の文化祭に行って来た。

_18(Sun)

ウワーン yarv-dev になんか沢山。


昨日は、OSC2005-Fall でした。それ以前に、るびまのインタビューでした。

  • 9:00 学校へ。プロジェクタをかついで現地へ。
  • 10:00 現地へ。2F しか頭になくて、展示会場が B2F だと教えてもらうまで気づかなかった。超あせった。
  • 12:30 だらだら。
  • 12:55 ルノワールじゃなくて、うささんを発見。
  • 13:00 インタビュー開始。兄弟、咳さん、うささん。この面子で2時間は短すぎた。なんかスゲーもったいない。でも、またやるわけにもいかんし。
  • 15:00 おわり。ルノワールの会議室を借りたので、時間を守らないといけない。もうちょっとさくさくと聞いて、生い立ちとかなんとかに時間を割いたほうがよかったかもしれず。本当にありがとうございました>インタビュー時にいらっしゃった方。ガクガクブルブルしていた会議室代および飲み物代はうささんに全額おごってもらう。なんて太っ腹なんだ。
  • 15:45 会場に戻り。
  • 16:00 Rubyの会セミナー開始。なんか、講師として紹介されそうになって、思わず担当ソースが無かったんで断ったんだが、別に断る必要が無かった、というか流れをぶちきってすみませんでした。
  • 16:10 青木さんが10倍速くした、という Pukipa 添削後ソースコードを YARV ではさらに高速化! というネタはどうかと、なんとか YARV で動かしたが、結局 1.1 倍くらいしか高速化しなかった orz。ボトルネックは正規表現検索かね。となると、RD 系とか Hiki とかは高速化しないのか。RDTools とかは racc の関係で... と思ったら、racc は C で書いてるから関係ないじゃん! ガーン。
  • 17:15 ちょっと押したけど無事終了。いいセミナーだったと思う。青木さんが色々細かいところまで指摘して、最初に色々と示せてよかったんじゃないかな。ちょっとスクリーンでごたごたしたのがなんとも。やっぱ return は書かないなあ。書くのは多値を返すときだけ。そういえば、多値の話はどうだったんだろうな。わかる人は殆ど居なかっただろうし。しかし、個人の嗜好と、Ruby らしいプログラムのあるべき姿との境目はどの辺なんだろうね。「長いのは悪。でも、無理して短くするのはもっと悪」その境目は? 離島の話は、俺だったら別メソッドにした気がする。
  • 17:30 撤収。展示会場最後のひとたちだった。
  • 18:00 一人ぶらぶらしてたら、3人に会ったので、ゲーム屋も無さそうなのでロッテリア。
  • 18:30 懇親会場へ。はやすぎた。
  • 19:00 懇親会。4000円は高すぎ。なかなか他のコミュニティの方との交流ができない。YLUG のカーネル読み会は一度行ってみたいなぁ。
  • 21:30 てきとうに喫茶店へ。deb とか gem とか大変だなぁ。
  • 23:30 おしまい。
  • 24:00 今後について検討。温泉は温泉らしい。
  • 01:00 学校へ戻り。

そういえば、dRuby本、レシピブックにサインしてもらったというのを忘れていた。


def hoge
  case huga
  when foo then :foo
  when bar then :bar
  when boo then :boo
  end
end

def hoge
  val = 
    case huga
    when foo then :foo
    when bar then :bar
    when boo then :boo
    end
end

みたいなソースコードを私は平気で書くんだけど、どうなのかな。


ソースコード添削会なんてどうかな、とちょっと思ったんだけど、考えてみれば RHG 読書会は青木本添削会じゃん。


多値を導入したとして、望ましい挙動を考えてみようか。

def values
  return 1, 2 # multiple values
end

def foo *args
  args
end

*[1, 2]   # multiple values? or somthing else?
[*[1, 2]] # what does it mean?
[values]  # what does it mean?
[*values] # what does it mean?

a, b = values  # multiple assign and multiple values
a, b = *values # multiple assign and splat multiple values
               # what does it mean?

foo(values) # what does it mean?
            #   foo(1, 2) or
            #   foo(1)

foo(*values) # what does it mean?

def values2
  values # multiple values? single value?
end

a, b = begin
        1, 2 # multiple values?
       end

a, b = (c, d = values) # what does it mean?

Please give me any suggestion.


a, b = (c = values)
a, b = (c, d = values)
a, b = (c, d, e = values)
a, b = (c, * = values)
a, b = (c, *d = values)

は、どうなるべきか?


a, b = [1, 2]
a, b = [1, 2], values

多値の実現方法として、VM (スレッド)情報に現在のコンテキストにおける「多値フラグ」「多値の数」「多値の格納場所」を作っておいて、それを使いまわすことにする。


def values
  return :a, :b
end

  values を呼んだ状態
    Thread.values_size #=> 1
    Thread.values      #=> [:b]
    スタックトップには :a が積まれている。

a, b = values

  expandarray は、values をまず展開する。  
 値が一個なので、まず Thread.values_size > 0 か見る。で、true
  多値らしいので、多値を展開する。スタックに :b を改めて積む。
  b にスタックトップを代入。
  a にスタックトップを代入。

さて、Thread.values_size をいつクリアするのか?

  • expandarray が、クリア?
    • そうすると、a, b = (c, d = values) が解決できない
      • これは、クリアするときとしないときのフラグを用意すればよい?
  • 式の終わりでクリア?
    • そうすると、無駄なクリアが増えすぎる
a = values
b, c = d

このとき、Thread.values_size をいつクリアする?


call-with-values で消費する多値は、もうそこで終了だから楽だよなー。


def values
  return 1, 2
end

def foo *args
  args
end

foo(values)    #=> [1]
foo(*values)   #=> [1, 2]
foo(values, 3) #=> [1, 3]

ary = [4, 5]

foo(ary)  #=> [[4, 5]]
foo(*ary) #=> [4, 5]
foo(ary, 6) #=> [[4, 5], 6]

こんな感じかなあ。

def iter
  yield(values)
end

iter{|a|
  # a => 1
}
iter{|a, b|
  # a => 1, b => 2
}

def iter
  yield([1, 2])
end

iter{|a|
  #=> [1, 2]
}
iter{|a, b|
  #=> [1, 2], nil
}

でいいのか?


def method *
end

def method a, *
end

#=>
t.rb:2: syntax error
t.rb:5: syntax error

は、バグだよね。多分。

_なかだ(Sun Sep 18 10:40:51 JST 2005)

 *のあとに;を入れると通るということは、継続行と見なされている?

_shiro(Sun Sep 18 13:26:47 JST 2005)

多値の数のリセットはかなりまめにやらないと結構はまります。Schemeでも、多値を必ずcall-with-valuesで受けるとは限らないので、例えばこんな場合:

(begin (values 2 3) 1)

エラーにする処理系もありますが、許容する場合、最後のリテラルの1を積むところで多値の数を1に直しとかないと、その直前の多値の数2が残ってて悪さをします。 結局、あらゆる式の評価後に多値の数をセットすることを原則にしといて、明らかに必要無い箇所のみで選択的にセットを避ける、という方向の方が安全だと思います。

どうしても多値の値のセットのオーバヘッドを避けたいなら、多値を生成する場合とそうでない場合でリターンアドレスを変えるChezScheme方式が使えるかもしれません。 http://portal.acm.org/citation.cfm?id=156784

_17(Sat)

う、updatedb が失敗する。/var/tmp の空きが少ないとか。ガーン。/var に 1 GB しか付けなかったのが原因だが。はてどうやって対処したもんだか。

一番でかいのは /var/cache で 400MB 消費、と。

385M    /var/cache/apt

これが一番でかいのか。


libapache-mod-ruby を入れて、apache2 で出来ないなあ、と思ってたら、libapache2-mod-ruby という、そのままずばり、があったのか...。

_mput(Sat Sep 17 12:16:17 JST 2005)

 うちでは使わないのでupdatedbはとめました……

_ZnZ(Sat Sep 17 19:20:35 JST 2005)

 apt-get autocleanとかapt-get cleanすればいいのでは? > /var/cache/apt

_通りすがり(Sat Sep 17 19:29:29 JST 2005)

 /var/cache をシンボリックリンクで別パーティションにとばすとか、 /var/tmp をシンボリックリンクで別パーティションにとばすとか、 updatedb 実行時に環境変数 TMP を指定して一時ファイルを別パー ティションに作るとか…

_16(Fri)

「日本全国で同じ病名を使ったら気持ち悪くありませんか?」

情報処理 vol.46、No.9、pp 1061

唖然。


ソースコード添削、著名人ばかりですよ。マジで(俺除く)。

もうちょっとリークすると、レシピブック必携ですよ。


とても眠い。


dRuby 本も必携かもしれない。

_15(Thu)

RType いいなぁ。どれくらい速度が出るんだろう(結局そこかよ)。

_oxy(Fri Sep 16 00:49:22 JST 2005)

 10万回ループで3秒かかったり、無茶苦茶遅いです。これはyarvに変換するしかありませんね;p

_ささだ(Fri Sep 16 09:17:33 JST 2005)

 ぜひ頑張ってくださいませ。楽しみにしてます。

_14(Wed)

見なかったことにしよう(笑)。


尊敬する(略)。いやはや、われながら根性が悪い。


なんとなく、最近宇宙でなんかする物語を見て面白いと思う。しかし、合体はないだろ、合体は。


コミットすると言っていながらコミットしていなかったので、コミット。

この修正で、vm_opts.h というファイルを編集すると VM のための最適化を付けるか付けないか変更できるようになる。stack caching 以外は付けるように変更。

もし、このパラメータを変えた場合は、make incs としてソースを再生成しないといけない。


やっぱり融合系もデフォルトでは外すことにしようっと。

と思ったら、デフォルトでは全部消すことにしていた。このままでいいや。


今日はスパコンの日。


スパコンだった。

_13(Tue)

今度新宿でインタビューしたいんだけど、どっか出来そうな場所知りませんか?

  • 多分4人
  • 土曜日
  • 13:00 〜
  • 出来れば個室代など無いところ

滝沢閉まっちゃったんだよねぇ。


未踏の目的は開発じゃなくて人材発掘だから。

という建前なので、少なくとも放り投げることが悪いとは思わないです。とか言っておかないととか言う。ちなみに、オープンにすればいいというものでも無いですよね。

しかし、結構注目してたんだけどなぁ。


最近、はてなだいありーなどを見ていると、Rails についての話が一杯だ。


Ruby の会のセミナー、抽選会と時間が被ってるらしい。残念。

_まつもと(Tue Sep 13 09:37:30 JST 2005)

 「オープンにすればいいというものでも無い」わけではないと思います。だってソースが自由でないとそもそもなにもできないから。それは最低限確保す べき レベルだと思います。

_みずしま(Tue Sep 13 14:30:09 JST 2005)

 未踏は、別にソースを公開することが主眼ではないと思うので、 ソースを公開しないことを批判するのは何か違うんじゃないかと思います。

_ささだ(Tue Sep 13 18:18:57 JST 2005)

 個人的にはオープンにすることが免罪符にならないか心配です。

_ささだ(Tue Sep 13 18:20:37 JST 2005)

 コメントは編集できるので、直したければ直してください。

_まつもと(Tue Sep 13 23:28:39 JST 2005)

まず、私が批判しているのは「ソースを公開しないこと」じゃなくて、「開発成果を無駄にする」ことです。

で、「投げ出すなら」_せめて_「自由なライセンスをつけて公開してほしい」ということが言いたかったわけです。これを理解していただければ「ソースを公開しないことを批判する」とか「オープンにすることが免罪符にならないか心配」とかは当たらないということが分かっていただけるのではないかと思います。

未踏ではオープンソースにしていないものもたくさんありますが、そのすべてが私の批判の対象ではありませんし、それらに対してオープンソースにせよというつもりもありません。成果を「投げ出し」かつ「適切なライセンスで公開していない」の両方の条件が成立するプロジェクトは、投資の成果が全く無駄になっているように感じます。たとえ未踏の目的が人材発掘であったとしても、開発成果を無駄にしてよい理由にはならないと思います。

未踏の目的がオープンソース支援でないのは当然のことで、だから、「オープンにすることが免罪符にならない」ことも自明だと思います。

_まつもと(Tue Sep 13 23:31:10 JST 2005)

 さらに言えば、最初の記事はMYCOMの記事が正しいことを前提としたものでしたが、開発者の高橋明生氏には別の言い分があるようです。

_ささだ(Wed Sep 14 02:04:43 JST 2005)

 個人的にはオープンソースにすることが無条件でいいことだとは思ってなかったりするんですが、ネガティブなコメントなのでこの辺で。

_まつもと(Wed Sep 14 08:59:14 JST 2005)

 私も「オープンソースにすることが無条件でいいことだとは思ってなかったり」するんですが、それは今回の話とは関係ないのではないかと。

_ほげ(Wed Sep 14 11:40:02 JST 2005)

 未踏の目的が「ソフトウェア産業の人材育成」なのか、「これまでにない新しいソフトの開発促進」なのか、あいまいなのが問題なのではないかと。人材育成が目的なら人材が育ったので良しとできるでしょうし、開発自体が目的なら、開発成果をお蔵入りさせるのはどうなの?といえるでしょうし。まあ、「これまでにない新しいソフトを作ることのできる人材の発掘」ぐらいが本当の主旨ではないかと思うのですが。

_12(Mon)

__send__ と invokemethod の違いがわからにゃい。


次も RHG 行けないんだなあ。


帰宅。


第三の嘘読了。

_ogino.(Mon Sep 12 17:51:17 JST 2005)

 それはかなしい。<次回

 ずらすとか..。

_babie(Tue Sep 13 10:37:48 JST 2005)

 だんだん面白さが下っていくよね>悪童日記シリーズ

_なかむら(う)(Tue Sep 13 15:02:22 JST 2005)

 どうして3冊まとめて発注してからそんな大事なことを orz

_babie(Tue Sep 13 18:05:42 JST 2005)

 3作とも文庫で買いなおすぐらいに面白いですよ。1作目が群を抜いているだけで。主観だし。

_ささだ(Tue Sep 13 18:14:09 JST 2005)

 どれも違う雰囲気で面白かったけどな。

_11(Sun)

色々な話が。

_10(Sat)

パーサを弄らないと、これはまずい気がする。今のパーサを自由に弄ってよい、ということになれば、色々といじらないと。

なんか、yield *[1] と yield [*[1]] の構文木が同じなんだよね。わけがわからんですよ。本家はどうやって区別してるんだろう? さっぱりわからん。


rubyconf 190人が上限なのか。


うぁ、わかった。node->nd_state というのがあったのか。


def m
  yield([1, 2, 3])
end

m{|a, *|
  p a #=> 1
}

は、どうみても変な気がする。

def m
  yield([1, 2, 3])
end

m{|a, b, *|
  p a
}

を考えれば、そうでもないか。


{|a, *|}{|a, |} はたぶん一緒だよね。で、どちらも対応してないけど。どうしようかな。


というわけで、今週の裏目標は、ブロックの rest arg に対応(optional arg はまだ当分対応しない)。


単体で動かすと動くのに、テスト全体を動かすとなんか死ぬ。何がいけないんだ。GC でもなさそうなんだよな。わけわからなさすぎ。


金を下ろすのを忘れていたのだよな。どうしよ。


で、2時間しか寝ていない。持つかな。


デモの発表終わり。RubyConf もこんな感じで終わらせればいいのに。

_9(Fri)

そろそろ多値について真剣に考えなくちゃいけない気がするなぁ。

a = *[1]
p a #=> [1]

は、明らかに間違いだが、

def m
  return *[1, 2]
end
a = m
p a

を考えると、どうしていいものかわからない。

a = *[1, 2]
p a #=> [1, 2]

こんなのもあるし。

一個、Array の要素数が 1 だったら中を取り出すってのをはさむか。嫌な命令だなぁ。なんかで代用できないかな。


というわけで、splatarray という命令を一個くっつけた。


るびま、一周年記念というわけで、コメントを関係者様から集めよう、ということになりました。というか、俺がやりたかっただけ。

で、メッセージクレクレ、というメールを実に数十通送ったわけですが、どうやら笹田spam と呼ばれていたそうです。

...反論が出来ない...。

ご協力いただきありがとうございました。


AMD Code Analyst というソフトの存在を知った。これで AMD のプロセッサ上でパフォーマンスチェックが出来る、と思ったら cygwin gcc でコンパイルした関数の名前を表示してくれない。色々便利そうなんだが、これが出来ないために非常に残念だ。VC をこのマシンに入れようかなあ。

あと、イベントカウンタを4つ用意して、任意のイベント(キャッシュミスとか)の回数を測れるようなんだが、表示が Event 0x43 とか書いてある。そんなの書かれてもわかんねーよ。

VTune にはなかなか及ばない。


OSC2005-Fall、定員とかどうなのかな、って思ってたら、別ページだった(OSC2005-Fall - Event Reserve)。

日本Rubyの会も出すそうです。登録はお早めに。

mysql, snort が多いなあ。なんでだろ。ニーズがあるということか。


今度は [*[]]、[*nil]、[*[1]] という式がうまく扱えないことがわかった。なんでだろー。困った。

_8(Thu)

・・・OOPSLAのポスターって、会期の一部、じゃなくて、全日やるの!? ずーっと張り付いておくのは無理だなぁ。


nokadaさんが票を着実にのばしてる。

_7(Wed)

9号執筆はいろいろあったので、ちょっとづつ書いていくつもり。


http://slashdot.jp/comments.pl?sid=274771&cid=794683 雑誌ごっこで Ruby ドキュメントは腐ってるらしい。

こういう見方もあるんだなあ。しかも興味深いらしい。


プレゼント、感想も一緒に、というのはまずかったかもなぁ。批判が書けなさげ。感想の内容は抽選と一切関係ないので、どうぞ思うままに書いてくださいませ>感想


せめて Rubyist Magazine と書いてくれ...。


言語仕様と言語実装は関係ないんじゃなかろうか...。

_6(Tue)

Rubyist Magazine 0009 号をリリースしました。お楽しみください。

るびまはおかげさまで一周年を迎えました。今後ともよろしくお願いします。


今回はまた大変だった...。


投票もこっそり更新。というか、どう見ても記事大杉。


あれ、いつの間にか特大号になってるぞ? 別に増やそうと思って増やしたんじゃないんだが。


ツンデレは現代用語なのか・・・。


るびまは知名度が大変低いので、よかったら宣伝したってください>各位。


http://slashdot.jp/comments.pl?sid=274771&cid=794522 笑ってしまった。

_5(Mon)

なんで俺は複数の作業を一度にできないのかな。

_ぼ(Mon Sep 05 19:22:09 JST 2005)

 ユニプロセッサ、シングルスレッド・シングルプロセス、プリエンプション不可…

_arai(Mon Sep 05 23:27:13 JST 2005)

 わたしはメモリが小さいらしく、さいきんはしょっちゅうスラッシングしてとまってます。。。

_なかだ(Tue Sep 06 11:12:24 JST 2005)

 コンテキストノスイッチハ オロオロアルキ ミンナニスラッシングトヨバレ

_4(Sun)

角谷さんのスライドを見る。字が綺麗だなあ。

Rails の話は、できればるびまも紹介して欲しかった。紙じゃないと、やはり駄目なんだろうか。

しかし、ネタ部分は黒塗りなのか。見たかったなあ。


Rabbit 使いたいなー、と思っても、Windows で使う方法がわからないのですぐにあきらめる。都合、どうしても PowerPoint を使わなくちゃいけない場面も多い。うさぎとかめ、いいなぁ。


はて?

_kou(Sun Sep 04 17:06:21 JST 2005)

 助田さんが使えたと書いていましたよ.http://homepage1.nifty.com/markey/memo/200508.html#082803

_ささだ(Sun Sep 04 22:02:59 JST 2005)

 RD だけだとやはりつらいので・・・。

_かくたに(Mon Sep 05 09:42:44 JST 2005)

 客層を考えると紙のほうがアピールできるかと思いまして。るびまはjaでRailsググれば1ページ目ですし。

_3(Sat)

エマ6巻読了。なんかすごい話になってるんだな。


グインサーガ102巻読了。


そういえば、LLDN で青木さんが「刹那的な若者〜」を「殺那的な若者〜」と書いていたのを思い出した。あれは何かのネタだったんだろうか。

_arai(Sat Sep 03 20:06:42 JST 2005)

 お、エマでたんだ。かわなきゃ

_青木(Mon Sep 05 00:05:39 JST 2005)

 ただの誤字です

_2(Fri)

コメントの一部分をコメントアウト、ってなんか面白いと思った。

_1(Thu)

JSASS2005 二日目。


未踏ユースブースト会議。うぅ、こっちのほうが面白そうなんだよなぁ。


発表終わり。

Sasada Koichi / sasada@namikilab.tuat.ac.jp
$Date: 2003/04/28 10:27:51 $