トップ «前の日(03-06) 最新 次の日(03-08)» 追記

2003-03-07

_ 今度は Ruby 開発者まつもとゆきひろ氏へのインタビューを

募集しています。

http://slashdot.jp/articles/03/03/07/0413248.shtml?topic=86

期限とかあるのかな?

聞いてみたいことは、、、やっぱ Ruby の入り口かなぁ。でもこれは開発者よりも Ruby Hacker に聞くべきか。あとは ActivePerl みたいな distributer というか Porter の登場を期待していますか? とか。個人的には期待しているのですが。やっぱ Perl も ActivePerl の登場は大きかったと思うし。

Tags: Web

_ Phoenix にしてみた

brussy テーマで説教講座 EntranceHole を開いてみたところ

ブックマークを吐き出すことに成功したので、Phoenix 0.5 + Brassy Theme にしてみた。

よい感じ。Safari 風なような、成金趣味のような。

Tags: 日々 Web Tool

2004-03-07

_ Unison は rsync より使えそうかも

Unison のマニュアルをちまちまと訳し始めたのだが、Unison は rsync の苦手な「ある特定のファイルやディレクトリだけをコピー対象とする」ことが容易にできそうだ。この点だけでも rsync を Unison で置き換えるメリットは大きいと思う。

Tags: Tool

_ cygwin の問題解決?

Updated: cygwin-1.5.6-1 に、

Don't send SIGHUP on CTRL_LOGOFF_EVENT to processes running in invisible Windows stations (like services). (Corinna Vinschen)

という記述を発見。

これで 1.5 になってから悩まされていた問題は解決か? 現在の dll は 1.5.5 なので明日早速上げてみよう。ちなみに現在の最新は 1.5.7。これで解決すれば ssh on SFU の実験は必要ないな。ついでに 1.5.7 では bash のハングなんかの問題も解決する、と。うむ。

Tags: MS Tool Unix

_ CVSユーザのためのSubversionガイド

Subversion for CVS Users by Mike Mason の wakatono 氏による翻訳。

Tags: Tool

2005-03-07

_ 眼鏡の鼻当て修理

眼鏡歴に反して、今まで泥酔して眼鏡をひん曲げた以外に眼鏡を壊したことはなかったのだけど、今している眼鏡は一昨年末にワイヤーが切れるなど、比較的手の掛かるものになっている。やはり舶来ものは壊れるのか。

今回は鼻当ての部分がいきなり取れた。というかねじ止めしている部分で折れたという表現が適切なんだけど、折れるとか割れるという表現を使うと鼻に当たる部分が折れたり割れたりしていそうでなんだか大げさに聞こえる。まぁそれはともかく、これを修理したんだけど、

鼻当ての修理ってどこでもタダでできるんですか。

知らなかった。今回は近くのメガネトップで直したんだけどにこやかに無料で交換できるものと500円掛かるものがございますが?と聞かれた。今までと同じものでいいですと答えたら無料で交換できるものだったのでそれでお願いした。ここの店で買ったわけじゃないんだけど、こういうのも元の眼鏡の値段に入っているんだろな。

でも実は微妙な違和感が残っている。というのも自慢じゃないが私の顔は歪んでいるので鼻に当たる部分と耳に当たる部分の角度のチューニングは繊細な匠の技を要するのだ。基本的にはデフォルトの状態で自分の視点で言って左前方向に眼鏡がずれていくので、これを止めるために鼻の左側と右耳の後ろに負荷が掛かる。この力をうまく逃がしつつ眼鏡がずれていくのを防がなければいけない。おまけに私はどうもメガネなどの圧力が顔に掛かることに対して敏感で、

ちょっとでもバランスが悪いと痛くなってしまう

のだ。今まではある店に何度か通いながら調整してもらっていたのだが、今はその店はない。はてどうしたものか。

Tags: 日々

2008-03-07

_ run-parts(periodic)で mail の送信先を変更する

いやなんかね。cron の管理が面倒で面倒で。とにかく登場するファイルの数を減らしたいわけです。

crontabファイルとスクリプトの氾濫

cron の設定管理は意外に難しい。crontab ファイル一つにすべて書くと見にくくなるし、だからと言って Linux で cron.d/ 以下に分けて書くと何時にどういうジョブが走るのか、全体の見通しが悪くなる。システム全体に関わるジョブを実行ユーザーが root じゃないからという理由で crontab コマンドを使って設定するなんてもってのほか。

また、cron.d/ 方式は crontab と実際に実行するスクリプトがそれぞれ別個に増えていく方式なので、煩雑さに拍車がかかる。

というかそもそも一つ一つのスクリプトについていちいち細かく実行時間を設定したくない。

解決案 run-parts(periodic) の活用

ではどうするのがよいのだろうと思い悩んだが、

  • 特別負荷が高くなく
  • 順番に依存しない処理

であれば、daily, weekly, monthly のように run-parts(periodic) を活用するのがよいように思う。この方法は

あるディレクトリ以下に実行するスクリプトを直接置くだけ*1

という気軽さがあるし、crontab ファイルは増えないので実行スクリプトの管理だけに集中することができる。

run-parts(periodic)活用時の MAILTO 問題

crontab は独自に MAILTO や HOME などの変数を解釈してくれるし、スクリプトを実行するユーザーも個別に指定できる。これを活用することで permission の問題に対応したり結果の送信先を柔軟に変更できるのだが、run-parts(periodic) を利用した場合は残念ながら cron が run-parts を実行するユーザーが誰であるかに関係なく root 宛に mail が届く。*2

この送信先を変更したければ

run-parts DIR | sendmail ADDR

として明示的にメールの送信先を変更するしかないみたい。

またこの方法で変更した場合に届くメールは当然 cron からの通知ではないので subject が自動で設定されたりはしない。man sendmail.

cf.

*1 ただしファイル名に注意。ルールに合わないファイル名のスクリプトは無視される。

*2 みたい。今回は run-parts でしか試してないけど。


2011-03-07

_ 今さらSinatra最低限メモ

今度は Sinatra. 次もすぐに動かせるように公式のドキュメントを圧縮する感じで、自分の欲しい情報だけ。アプリを書く以前のレベルで、まずはページを表示できる状態を目指す。

実は昨日の kanazawa.js の成果その2

環境

今回の環境は

  • MacOSX 10.5
  • Ruby 1.8.7
  • Sinatra 1.1.3
  • Ruby 1.9.2
  • Sinatra 1.2.0

で確認した。Sinatra のバージョンが合ってないことに特に意味はない。

インストール

(ry

動かし方

1ファイルの場合は
$ ruby app.rb

でもよい。例の感じで中に

require 'rubygems' unless defined? ::Gem
require 'sinatra'

get '/' do
  'Hello, World'
end

で終了。デフォルトで port 4567 で起きる。

ちなみにこれだけで response header とこの文字列だけの response body が返る。PHPer 的には print や echo で出力したくなるけどそれは間違い。これは

get '/' do
  return 'Hello, World'
end

の return を省略してるだけ。return が response になる。rack の header を省略できると思えばいいはず。

設定とか分離したい

rack の流儀に則って config.ru を用意(別名でもいいけど)。

config.ru

require 'rubygems' unless defined? ::Gem
require File.dirname( __FILE__ ) + '/app'

run Sinatra::Application

app.rb

require 'sinatra'

get '/' do
  'Hello, World !'
end

この場合は rackup する。*1

$ rackup

デフォルトで port 9292 になる。rack の流儀で変更可能。

$ rackup --port 80

※ ただし Un*x なシステムでは 1024 以下は特権ポート。のはず。

Handler を明示すれば option を与えられるけど、Handler を与えない方針なので以上。

自動でReload

mod_php や Rails の development 環境に慣れてしまったのでこれがないとやってられない。方法は3つ。

  • Rack::Reloader
  • Shotgun
  • Sinatra::Reloader

What happened to reloading in Sinatra 0.9.2? - Sinatra: Frequently Asked Questions

Rack::Reloader

普通の Rack Middleware

use Rack::Reloader

すればオッケー。でもちゃんと動かないらしい。動いてるように見えるけど、そうとは限らないということか。却下。

Shotgun

rtomayko/shotgun - GitHub

shotgun の名前がインパクトがあってよく覚えてたんだけど、今 Sinatra のサイトで読むといちばん遅いのと、fork を使うので JRuby や Windows で動かないとのこと。あやや。

インストールはもちろん

gem install shotgun

これは普通のアプリの起動にも使えるし、

shotgun app.rb

rackup 代わりにもそのまま使える。

shotgun [config.ru]

今度は port はデフォルトで 9393 になる。

Sinatra::Reloader
gem install sinatra-reloader

個人的には予想以上に依存が多い。

if development?
  require 'sinatra/reloader'
  Sinatra.register Sinatra::Reloader
end

で使える。Rack Middleware の要領で use ってやったら怒られた。Sinatra Extension と Rack Middleware は違うのね。

あと当たり前だけど

reloaderに関する書き換えを行うときは再起動した方がいいよ。

ディレクトリ構成とsetによる設定

project/
 ├── app.rb
 ├── config.ru
 ├── public/
 │     └── javascripts/
 │             ├── LAB.js
 │             ├── application.js
 │             ├── jquery-1.5.1.min.js
 │             └── jquery.Router.js
 └── views/
        ├── hello.erubis
        ├── index.erubis
        └── layout.erubis

Rails流とちょっと違う。

この public, views はそれぞれ以下のように設定できる。

README.rdoc

set :public, File.dirname( __FILE__ ) + '/static'
set :views, File.dirname( __FILE__ ) + '/templates'

要するにアプリケーションのファイルを基準にして自分で決めたきゃ決めろと。この設定方法は Capistrano に似てるなぁ。

何が設定できるかはここを見るといい。

Sinatra: Configuring Settings

root も変更できる。

テンプレートの選択とrender

基本系
get '/' do
  erb :index
end

こんな感じ。これで

  • index.erb を探して
  • erb でレンダリング

という意味になる。拡張子の変更はできるのかなぁ。できないような気がする。中で render メソッドを読んでるんだけど、ちゃんと追いかけると何か分かるかも。

render は最後に
erb :index

って書き方だけだと index.erb を表示用に使うよ、っていう宣言に見えちゃうんだけど、これはれっきとした render メソッドの呼び出しなので、処理はこの前に書くこと。と言うか

erb :index とかは最後に書け

の方が分かりやすいか。

erubis でHTMLのエスケープをデフォルトに

Rails 3 以降デビューなのでこれがないとやってられない。

require 'erubis'

set :erubis, :escape_html => true

get '/' do
  erubis :index
end

こんだけ。

オブジェクトの割り当て

これは Rails の View に似ていて(同じ?)、

  • インスタンス変数は直接参照可能
  • ローカル変数は明示的に :locals で割り当て

という方法を採る。

app.rb

get '/' do
  erubis :index, :locals => {:key => value}
end

views/index.erubis

<%= key %>

こんな感じで value が表示できる。

layoutファイル

layout ファイルは

views/layout.#{ENGINE}

になるはず。layout ファイルと個々のテンプレートで種類を変えることができるのかどうか分からない。たぶんしない方がいいと思う。

erubis の「エスケープしない」出力

layout.erubis

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title><%= @title %></title>
  </head>
  <body>
    <h1><%= @title %></h1>

    <%== yield %>

  </body>
</html>

こういう風にしとくと個々の

erubis :index

などの中身に HTML をそのまま書くことができる。

<%== %>

が決め手。

参考

*1 Handler を直接 config.ru に書く方法もあるんだけど、それだと環境を変えるためにはいちいち書き直さなきゃいけないから嬉しくないと思う。


2012-03-07

_ kanazawa.js v1.7でJSTDD Introと銘打って話します

来る 3/31(土)に kanazawa.js v1.7 が開催されます。参加申し込みはこちら!

kanazawa.js v1.7 - Back to Basics - : ATND

今回はなんと Mozilla さんと共同開催でかつ node.js 方面からも刺客(講師)が来るという豪勢な内容になっています。

そんな中で JavaScript での TDD について話すことになりました。まぁぶっちゃけ二つ返事で返しちゃったんですが、あとでプログラムを見てからアウェイ感にやられております。メインセッション扱いですが、聞く方はポカーンじゃないですかね、これ(笑

正直言うと不安はあります。

  1. 嘘を言うんじゃないか
  2. もっと良い話をできる人は他にたくさんいる

1 については、なんだかんだで自分はそんなにきちんと TDD を学んでおらず、我流ですし、ペアプロの機会にも恵まれませんので、自分を見直すことが難しい状況です。文字で読める情報はなんとか追ってはいますが、誤解を与える可能性が消えません。

まずここがいちばん怖い。

2 についてはまぁ、JavaScript x TDD x kanazawa という組み合わせになってしまうと話せる人はたぶんそれほど多くはないので、東京で話すことに比べれば気は楽です。

ということで、1 に関する不安を減らすために、

当日話す内容のスライドのレビューをしてくれる方を募集します。

3/11(日) 0:00 ( 3/10 24:00 ) までに「レビューしたる」と wtnabe at gmail dot com までお送りいただくか、メールアドレスを公開されている方は @wtnabe によこせと言ってもらえれば喜んで PDF を送りつけて差し上げたいと思います。

まぁ現時点で公開しちゃってもいいっちゃいいんですけど、一応叩いてもらってから当日に公開しようと思っています。

あ、出席予定の方は面白みがなくなるのでご遠慮ください(笑)


2016-03-07

_ Shift_JISの範囲外の文字を検出、見える化したい

まだちょっと悩んでるけど一応できたのでメモ。

若者のiconv離れ

とあるデータ加工作業があって、その中で Shift_JIS の範囲外の文字を置き換えていくという作業を行う必要があった。具体的には (株) とか「はしごだか」とかああいう文字ね。

で、これまでその辺はある程度お任せにしていて、必要になったら(実はここがミソ)自分が手で iconv をこんな風に

iconv -f sjis -t sjis filename > /dev/null

叩くことでダメな文字を指摘していた。iconv は nkf のようにいい具合に skip して処理しないので、Shift_JIS の範囲内で変換できない文字のところで以下のようにエラーを吐いて止まる。

iconv: filename:{line}:{col}: cannot convert

iconv なんてイマドキそんなに使わないのでは?と思いつつ古のワザをくり出していたのだけど、何せこの表示、見にくい。具体的には

普段テキストエディタで作業していない人には全然分かりやすくない

こんなことしなくても作業の練度が上がるとダメな文字が入ってくるパターンを学習して「だいたいこんな感じ」でいい具合に弾けるようになる。ところがこの学習の効いていない人に引き継ぐと、途端に難しくなってしまう。じゃあ iconv 使ってもらうかというとそれは厳しいなぁと思う次第。

Rubyで書けるのではと思ったら意外に難しかった

他にも加工を支援する必要があるのである程度のカタマリで rake task を用意していくことにした。*1そこで Ruby の Encoding でも不正な文字列が入っていると変換に失敗するので似たようなことはできるのではないかと思ってやり始めてみたら意外に奥が深かった。

結論から書くとこんな感じ。

  • 変換エラーで止まる際はどこの文字かヒントがない(バイト列は表示される)ので、 iconv よりも分かりにくい
  • Encoding#valid_encoding? は変換表に基づいて valid? の判断をしていないので、1文字ずつなめて valid でない文字の前もヒントととして表示してあげるといったことはできない
  • encode(enc, undef: :replace, replace: '??') みたいにするとダメな文字だけを特定しやすい文字に置き換えることはできる
    • ただし、全部同じ文字に置き換えられてしまうので、結局元のデータを修正する時は目視が必要
    • しかも問答無用で Windows-31J → Shift_JIS 変換を行ってはならない

全部ハマった。最後のものはどういうことかというと、

open(file, 'rb:Windows-31J').encode('Shift_JIS', undef: :replace, replace: '??')

で目的が達成できるかと思ったら、〜 がすべて不正な文字扱いになってしまう。

正しい Shift_JIS として記録されているのに Windows-31J として読み込んでしまうと 〜 を Shift_JIS の範囲外の文字として扱ってしまう*2。これを encode('Shift_JIS') してしまうと不正な文字だらけになってしまって意味がない。

結局こうなった

  begin
    open(f, "rb:Shift_JIS:UTF-8").read
  rescue Encoding::UndefinedConversionError => e
    fulltilde = "\x81\x60".force_encoding("Windows-31J")
    tmptab    = "\v".force_encoding("Windows-31J")

    s = open(f, "rb:Windows-31J").read.gsub(fulltilde, tmptab)

    diff = s.encode("Shift_JIS", undef: :replace, replace: "??".colorize(:magenta)).encode("Windows-31J").lines - s.lines

    if diff.size > 0
      puts ""
      puts f

      puts diff.map {|e| e.gsub(tmptab, fulltilde).encode("UTF-8")}
    end
  end

Shift_JIS から UTF-8 に変換できない時だけ Windows-31J として読み込んで、その後 Sift_JIS に変換を試みることで Shift_JIS に収まっていない文字を置き換える作戦。これでこの結果の画面は

  • ダメな文字を含む行だけが表示され、かつ
  • ダメだった文字はハイライトされている

ので、詳しくない人にも結構分かりやすい表示になるんじゃないか。

また、そのままだと 〜 が Windows-31J から UTF-8 へ変換される過程で Shift_JIS では扱えない文字となってしまい、軒並み undef になってチェックの意味を成さなくなるので、これは強制的に垂直タブに置き換えて問題なく動作するようにしている。

cf. String#encodeが変換できそうで変換できない文字 - ネットの海の片隅で

Tags: Ruby

*1 コマンドラインから作業するハードルがあるのは認める

*2 途中で UTF-8 に変換する際に対応関係が壊れるのか?