2013/02/23


mruby には元々、正規表現のコードが入っていました。標準では ifdef で無効化されており、有功にしてもコンパイルエラーが出る状態でした。それを IIJ さんが hack して使える様にしてくれていたのだけど、Matz としては思う所があってか取り込まれていませんでした。
もったいないなーと思い、それをしばらく最新にメンテしてたのですが、こちらも取り込まれる事はありませんでした。
おそらく軽量 mruby に標準で正規表現が組み込まれている事でのオーバーヘッドや、期待しないメンテナンス作業を嫌っての事だと思います。
おかげで通常の mruby では正規表現リテラルを含むコードはパースエラーとして扱われ、CRuby 向けに書かれたアプリケーションの移植の妨げになっていました。

ならばとばかりに、逆に mruby から正規表現を取り払う修正を pull-req しました。
Pluggable regexp by mattn - Pull Request #850 - mruby/mruby - GitHub

This solution closes following issues. #444 #719 #841 VM don't provide Regexp mruby provides basical...

https://github.com/mruby/mruby/pull/850
この修正は、「mruby としては // などの正規表現リテラルは内部オブジェクトとしては管理しない。その代わり、// を見つけたら Regexp というオブジェクトのインスタンスを生成する。」という内容です。
つまり mrbgems として正規表現拡張を取り込んでいる場合には、// が正規表現オブジェクトとして扱われ、/[a-z]/.match("a") といったコードも動くようになるという物です。
言うなれば
Bye Bye Regexp, But Welcome
といったところかと思います。メモリの少ないハードにのっけたい人などは、この mrbgems を入れなければいい、という事になります。
ただし mrbc で生成した RITE にリテラルが含まれないというバグがありましたが、さっき Matz が直してくれました。
ちなみにこれがどういうバグだったかというと、僕は /[a-z]/ を直接 Regexp.new("[a-z]") に置き換えていたのですが、これだと mrbgems を認識せずに実行される mrbc(RITEコンパイラ) が Regexp という識別がが認識できずにエラーになるという不具合で Matz はこれを Object.send(:new:Regexp, "[a-z]")
となる様な修正を入れてくれました。
これで、正規表現リテラルは実行時に評価される様になります。

それって実行時評価だよね、遅いんじゃないの?


CRuby ではコンパイル時にオペレーションコードとして正規表現インスタンスを起こしているので mruby と違う動きになります。
例えば、不正な正規表現パターンを書いた時には実行時まで知ることが出来ません。しかしながら通る事の無い正規表現リテラルまでコンパイルしてしまう CRuby よりも、僕は分かり良くていい気がします。 if false
  # 大量の正規表現
  # 大量の正規表現
  # 大量の正規表現
  # 大量の正規表現
  # 大量の正規表現
end
もちろん、実行時評価なのでループ内に正規表現リテラルがある場合には逐次生成されてしまうのは気にしておく必要があるでしょう。もしかしたら今後、リテラルから生成した正規表現オブジェクトをキャッシュする、なんてパッチも現れるかもしれません。

現在のところ、mruby から正規表現リテラルを扱える様にする為の mrbgems 実装は以下3つ
masamitsu-murase/mruby-hs-regexp - GitHub

mrbgem of Henry Spencer's Regular Expression

https://github.com/masamitsu-murase/mruby-hs-regexp
mattn/mruby-onig-regexp - GitHub

mrbgem of 鬼車's Regular Expression

https://github.com/mattn/mruby-onig-regexp
mattn/mruby-pcre-regexp - GitHub

mrbgem of PCRE

https://github.com/mattn/mruby-pcre-regexp
これの内、どれかを入れておけば正規表現が使える様になります。
HsRegexp を使ってリテラルを扱う為には現在のところ Regexp = HsRegexp とやる必要があります。Regexp = HsRegexp 出来る様になりました。

これら一連の動きを、bovi さんがブログ記事にしてくれています。ありがとうございます。
Pluggable RegExp - mruby.sh

The last couple of weeks were quite exciting from a RegExp point of view. The first big thing was mattn’s pull request of the IIJ RegExp Engine which is based on Oniguruma. This patch would have made the same RegExp Engine from the MRI also available in mruby. After one month of discussion and work on this patch the final decision was to close this ticket. This sounds sad but actually this is really good news, due to the reason that instead we decided to build a pluggable RegExp engine into mruby.

http://mruby.sh/201302190729.html
だんだん CRuby に近づいてきましたね。
Posted at by



2013/02/21


一般的なGo言語プログラマならば、HTTP Status code はすべて暗記していると聞きました。

しかし、僕は初心者なので、なかなか覚えきれていないので、IRC から HTTP のステータスコードをさがすのに便利なツールを用意しました。
go-httpstatusbot です。インストール方法は go get . として ./httpstatusbot と実行して下さい。 package main

import (
    "fmt"
    irc "github.com/fluffle/goirc/client"
    "os"
    "regexp"
)

var pattern = regexp.MustCompile(`^\s*(HTTP|http) ([0-9]+)\s*$`)
var httpstatus = map[string]string {
  "100""Continue",
  "101""Switching Protocols",
  "102""Processing",
  "200""OK",
  "201""Created",
  "202""Accepted",
  "203""Non-Authoritative Information",
  "204""No Content",
  "205""Reset Content",
  "206""Partial Content",
  "207""Multi-Status",
  "208""Already Reported",
  "300""Multiple Choices",
  "301""Moved Permanently",
  "302""Found",
  "303""See Other",
  "304""Not Modified",
  "305""Use Proxy",
  "307""Temporary Redirect",
  "400""Bad Request",
  "401""Unauthorized",
  "402""Payment Required",
  "403""Forbidden",
  "404""Not Found",
  "405""Method Not Allowed",
  "406""Not Acceptable",
  "407""Proxy Authentication Required",
  "408""Request Timeout",
  "409""Conflict",
  "410""Gone",
  "411""Length Required",
  "412""Precondition Failed",
  "413""Request Entity Too Large",
  "414""Request-URI Too Large",
  "415""Unsupported Media Type",
  "416""Request Range Not Satisfiable",
  "417""Expectation Failed",
  "418""I'm a teapot",
  "422""Unprocessable Entity",
  "423""Locked",
  "424""Failed Dependency",
  "425""No code",
  "426""Upgrade Required",
  "428""Precondition Required",
  "429""Too Many Requests",
  "431""Request Header Fields Too Large",
  "449""Retry with",
  "500""Internal Server Error",
  "501""Not Implemented",
  "502""Bad Gateway",
  "503""Service Unavailable",
  "504""Gateway Timeout",
  "505""HTTP Version Not Supported",
  "506""Variant Also Negotiates",
  "507""Insufficient Storage",
  "509""Bandwidth Limit Exceeded",
  "510""Not Extended",
  "511""Network Authentication Required",
}

func main() {
    c := irc.SimpleClient("httpstatusbot""httpstatusbot")
    c.EnableStateTracking()

    c.AddHandler("connected"func(conn *irc.Conn, line *irc.Line) {
        for _, room := range os.Args[1:] {
            c.Join("#" + room)
        }
    })

    quit := make(chan bool)
    c.AddHandler("disconnected"func(conn *irc.Conn, line *irc.Line) {
        quit <- true
    })

    c.AddHandler("privmsg"func(conn *irc.Conn, line *irc.Line) {
        if pattern.MatchString(line.Args[1]) {
            m := pattern.FindStringSubmatch(line.Args[1])
            if status, ok := httpstatus[m[2]]; ok {
                c.Notice(line.Args[0], status)
            }
        }
    })

    for {
        if err := c.Connect("irc.freenode.net:6667"); err != nil {
            fmt.Printf("Connection error: %s\n", err)
            return
        }
        <-quit
    }
}
使い方は... もういいですね。わかります。 今日の参考資料
http://blog.64p.org/entry/2013/02/21/121830
http://mattn.kaoriya.net/software/vim/20130221123856.htm
Posted at by




一般的な Web Programmer ならば、HTTP Status code はすべて暗記していると聞きました。

しかし、僕は初心者なので、なかなか覚えきれていないので、HTTPのステータスコードをさがすのに便利なツールを用意しました。
httpstatus-vim です。インストール方法は bundle かなんかで以下を追加して下さい。
mattn/httpstatus-vim - GitHub
https://github.com/mattn/httpstatus-vim
使い方は以下のとおりです。 4xx なコードを列挙する。 :HttpStatus 4
400: Bad Request
401: Unauthorized
402: Payment Required
403: Forbidden
404: Not Found
405: Method Not Allowed
406: Not Acceptable
407: Proxy Authentication Required
408: Request Timeout
409: Conflict
410: Gone
411: Length Required
412: Precondition Failed
413: Request Entity Too Large
414: Request-URI Too Large
415: Unsupported Media Type
416: Request Range Not Satisfiable
417: Expectation Failed
418: I'm a teapot
422: Unprocessable Entity
423: Locked
424: Failed Dependency
425: No code
426: Upgrade Required
428: Precondition Required
429: Too Many Requests
431: Request Header Fields Too Large
449: Retry with
40x なコードを列挙する :HttpStatus 40
400: Bad Request
401: Unauthorized
402: Payment Required
403: Forbidden
404: Not Found
405: Method Not Allowed
406: Not Acceptable
407: Proxy Authentication Required
408: Request Timeout
409: Conflict
500 ってなんだっけ? :HttpStatus 500
500: Internal Server Error
403 ってなんだっけ? :HttpStatus 403
403: Forbidden
Bad なんとかってなんだっけ? :HttpStatus Bad
400: Bad Request
502: Bad Gateway
とりあえず全部みるか。 :HttpStatus
今日の参考資料
http://blog.64p.org/entry/2013/02/21/121830
Posted at by