ruby

テストが通らなくて5時間泣いた話をしようか

class MyError < StandardError attr_reader :exception def initialize(exn) @exception = exn end end begin begin 1/0 rescue ZeroDivisionError => exn raise MyError.new(exn) end rescue MyError => exn p "rescue MyError", exn rescue Exception => …

String#succは、辞書順ではない

ぼけっとしてて気づいてなかった。"999"の辞書順で次の文字列は、"999a"や"9990"であって、"1000"ではない。 ["999", "1000"].max => "999" ["999", "999".succ].max => "999" 後者は直感的に変だと思うんだけど。ひとまず、適当に辞書順になりそうな感じの…

例外のキャッチ

rescueで例外を捕獲するときに、どうやってテストするのか、積年の謎だったんだけど、結局ソースコード読むことにして解決した。===でテストしてる。===はcase式で値を比較するときに使われる演算子で、大体クラスCのC.===はそのクラスのオブジェクトに対し…

ふむ

class A end $a = A class A ::A = String def f() p :f end def self.g p :g end def A.h p :h end end $a.new.f $a.g String.h まあ直感的かな。 class文の中でselfがいつ解決されるのか、ちょっと気になったのでした。

どこからreturnすんだよ

def g(x = [1].each {|x| return x }) 3 end puts g() 表示されるのは、1。これが実行できるんなら、 def g(x = (return 1)) 3 end もコンパイル時にrejectしなくても良いような気もするんだけど。

メソッドに引数が渡されたかどうか知る

昨日、ぼーっとしてて思いついたんだけど、前書いたやつは引数がわたされたかどうか確認するのに使えるじゃないか。 def f(x = (a=:a)) case a when :a # 引数渡されてない when nil # 引数渡された end end なんに使うのか知りませんが。

オプショナル引数について考える

def f(x1, x2, y1=:y1, y2=:y2, *z, x3, x4) end みたいなやつですね(Ruby 1.9)。ここで、y1、y2がオプショナル引数です。さて、このメソッドを呼び出したとき、どのように引数はバインドされるのでしょうか。 f(1,2,3,4,5,6,7) というメソッド呼び出しを考…

Ruby 1.9の地味な変更点(1.9.1-rc2)

BEGINでくくったブロックとその外がローカル変数のスコープを共有するようになりました. BEGIN { x = 3 } puts x バグかと思っちゃったよ. ていうか,ほんとになったのかな.実装はそうなってるみたいだけど.1.8はどうだったんだろう.

なんだこれ

node.hにあるNODE_OP_ASGN_OR、NODE_OP_ASGN_AND、NODE_OP_ASGN1、NODE_OP_ASGN2についてです。問題は、これがなんなのかということ。すぐに思い付くのはx += 1みたいのですが、これはパーサの時点でx = x + 1になります。じゃなんだこれ。まず、ORとANDです…

yieldから抜けるにはnext

breakでもreturnでもありません。

定数について考える

A = 3 class A end class B < A end これはどっちも実行時エラー。クラスはClassじゃなくちゃいけない。まああたりまえ。 A = Class.new class A end class B < A end これは行ける。これもあたりまえ。じゃあ、これは? Class = 1 class A end class B < A e…

alias

Ruby Reference Manualマニュアルには書いてないけど、再帰呼び出しがあるメソッドについては、aliasは関知しない。なにもしないんだから、書くまでもないとも言える。 def fact(n) if n==0 1 else n * fact(n-1) end end alias fact2 fact puts(fact2(3)) d…

困ったな

パーサが欲しいだけなので、PRELUDEは要らない。でも、コンパイルオプションを調べるためにはrubyスクリプトを実行する必要がある。PRELUDEなしだと、スタックトレースが出てくる。 とりあえず、一度Rubyのビルドから、やり直してみよう。

メソッド定義を考える

1.クラスにメソッドを定義する class Object def f() ... end end Object.instance_eval { define_method(:f) { ... } } 2.オブジェクトのクラスにメソッドを定義する a.class.instance_eval { define_method(:f) { ... } } 3.オブジェクトに特異メソッドを…

lambdaに型が無い

Rubyのlambdaメソッドの型は、すんごいナイーブには lambda : ('a -> 'b) -> Proc<'a, 'b>みたいな感じになると思っていた。Procは、call : 'a -> 'bみたいなcallメソッドを持つようなProcオブジェクトだと思ってください。しかし、id:sumii先生の記事を見て…

webrick/httpproxy

って、キャッシュってできないんですかね。

Arrayのインスタンス変数

ふとArrayやHashのインスタンス変数はどうなっているんだろうと思った.Rubyのインスタンス変数が定義されていると,かなりよくわからないことになってしまう. % irb irb(main):001:0> Array.new.instance_variables => [] irb(main):002:0> Hash.new.insta…

多相型がどれだけ使われているかを調べたいのだが、良い方法を思いつかない。というか、それを型推論というのではないかと小一時間(ry。そもそも、そのために先にライブラリとか構文とかを充実させる予定だったのが、意外な展開になってしまって焦ってる人。…

タイプチェック

テストのうちで、処理系が型検査してくれることを前提とすれば省略できるものはどの程度なのか、ちょっとgonzuiで調べてみた。x.is_a?(String)とかはいらんやろ。 $ cd gonzui-1.2/tests $ grep 'assert' *.rb | wc -l 242 $ grep 'is_a?' *.rb | wc -l 271…

longest match

Enumerable#injectを使ってみた。 require 'strscan' def longest_match(scanner, res) sz,regexp = res.inject([0,nil]) {|(sz,regexp),re| x = scanner.match?(re) (x ||= 0) > sz ? [x,re] : [sz,regexp] } yield(regexp, regexp ? scanner.scan(regexp) …

longest match

最長最左マッチ。 require 'strscan' def longest_match(scanner, res) sz = 0 regexp = nil res.each {|re| x = scanner.match?(re) if (x ||= 0) > sz regexp = re sz = x end } yield(regexp, regexp ? scanner.scan(regexp) : nil) end longest_match(St…

私には珍しく、カリカリ最適化してみる。*1 injectは遅かったのでeachに変更 正規表現リテラルを定数に代入して利用 String#+をString#concatに変更 メソッド呼び出しを最小限に 正規表現を見直して、eachのループ回数を最小限に 末尾再帰になっているメソッ…

longest match

/aa|a+/ =~ "aaaaa"とすると、"aa"がマッチするわけですが、これを"aaaaa"にマッチするようにする方法は無いものか。lexerを作りたいのです。

Rails始めました

デフォルトじゃあHTMLタグのエスケープとかなにもしてくれんのね。ASP.NETより、いらんことせんくて好印象。

to_xxx

to_str、to_int、to_ary、to_hash、to_io、to_regexp、to_procは、それぞれデータ型を暗黙に変換するためのメソッド。しかし、to_floatはない。to_intで代用するか。ちょっと困った。

今日のRuby

6.times { puts [1,2,3].collect {|d| rand(30) }.sort }某書類に書く日付を、半年間の毎月3日ずつランダムに生成するスクリプト。

limit.rb

pid = fork { exec ARGV[1] } Thread.start { sleep(ARGV[0].to_i) 10.times { Process.kill(2, pid); sleep(1) } Process.kill(9,pid) } Process.waitpidこの話はこれでおしまい。先週のGaucheの話とあわせて、簡易サンドボックスのできあがり。

子プロセスの実行を3秒で止めたい

limit.rbとかをこんな感じで pid = fork { exec ARGV[1] } sleep(ARGV[0].to_i) Process::kill(2, pid)作っておいて、 IO.popen('ruby limit.rb 3 "gosh ..."') { |io| ... }で、うまく行くような予感。Process::setrlimit*1だと、CPU時間しか計れないので、…

メモメモ

to_strとto_s http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-dev/18655to_sは、単純にオブジェクトを文字列に変換する以上の意味は無い。to_strは、そのオブジェクトが文字列として振舞えるようにする変換を定義することが目標。 puts(obj)が、to…

バグ?

% ruby -e "require 'time'; p Time.parse('Mon Sep 19 18:06:17 GMT+9:00 2005').to_s()" "Mon Sep 19 18:06:17 UTC 2005"GMT+9:00だって言ってるのに、UTCで帰ってくる。WinXP-SP2上のCygwinのruby 1.8.2で。マニュアルを読むと、そういう仕様っぽいことが…