トップ «前の日記(2008-10-29) 最新 次の日記(2008-11-12)» 編集

Route 477



2008-11-01

[web] Googleドキュメントの表計算で曜日を入力させる方法

今年の春から、家計簿を付けるのにGoogleドキュメントを使っています。最初はOOo Calcでやってたんだけど、 「Googleドキュメントならどこのマシンからでも更新できてよくね?」ってことで移行。

しかしですね、Googleドキュメントはなんと日付の書式指定で曜日を付けられないのです。つまり

1 | 2008年11月1日(土) | コーヒー | 120 |

みたいなことができない。しかも、OOoの文書からインポートしたてのときはちゃんと曜日が出てたんですが、 なんかセルをコピーしたり移動してるうちに一部分だけ曜日が出なくなった、これはキモい。

んで調べてみたところ

にて方法が紹介されていました。

1つのセルに日付と曜日両方を出すことはできないんですけど、セルを分けて、例えばA1に日付、B1に以下のような数式(?)を書く。

=IF(A1="", "", IF(WEEKDAY(A1, 2)=1, "月", IF(WEEKDAY(A1, 2)=2, "火",  IF(WEEKDAY(A1, 2)=3, "水",  IF(WEEKDAY(A1, 2)=4, "木",  IF(WEEKDAY(A1, 2)=5, "金", IF(WEEKDAY(A1, 2)=6, "土", IF(WEEKDAY(A1, 2)=7, "日"))))))))

と、

  |      A        | B  |     C    |  D  |
-----------------------------------------
1 | 2008年11月1日 | 土 | コーヒー | 120 |

のようになります。やったね!あとはB1をコピーしてB2, B3, ... に貼り付けていけばおk。(A行が空のところはB行も空になります)

しかしこんなことせんといかんのがいかにもなんだかなであります。今はDropboxがあるんだから普通にOOo Calc使おうかなぁ。

[ruby] %Qを使ったQuineにRubyの暗黒面を見た

暗黒面ブームに便乗してみる。

最近、人生初を書いて、結局$0かformatのどっちか使わんといかんのかなぁと思っていたところ、%Qを使ったQuineを発見。

Ruby版だけ引用すると、

lines = %{
print "lines = %{"
print lines
print "}"
print lines
}
print "lines = %{"
print lines
print "}"
print lines

でQuineになるとのこと。

一見どうなってるのか分からんっていうか「}"」のところで文字列が終わってパーズが通らないように見える…んですが、そういえば

括弧を区切り文字にした場合、対応が取れていれば 区切り文字と同じ括弧を要素に含めることができます。

%(()) => "()"

[リテラルより引用]

というルールがあるんだった…。なるほど。

まぁだからといって暗黒面といえるかというと、別にあって困るもんでもないし、いつか役に立つかもというか実際にQuineを書くときには役に立つことが 証明されたわけですし、仕様を書く人が苦労するだけのことで、何も問題はないですね!

(11/2追記:これ以外にもevalとかヒアドキュメントとかjoinとかいろいろあるそうです : http://d.hatena.ne.jp/shinichiro_h/20081102#1225569359 )

[ruby] Ruby1.9の紹介も兼ねて、「+暗が gsub できない件」について遅レスする

遅レスが辞書に入ってる(らしい)ATOKはさすがといったところですが、それはともかく。

Ruby 1.8の場合

うーん、JISコードなのが辛いところですね。EUC-JPか、SJISか、UTF-8なら -K オプション(or $KCODE)で対処できるんですが*1、 JISコードはネイティブでサポートされていないので、正しく扱おうと思ったら EUC-JP/SJIS/UTF-8 のどれかにいったん変換するのが良いと思います。

例 (EUC-JPを通す場合)

require 'kconv'
$KCODE="e"

str = "footestbar"
after = File.read("tasuan.jis").chomp.toeuc
puts str.gsub(/test/, after)  #=> EUC-JPで「foo+暗bar」と出力される

ここではスクリプトの最初で「$KCODE="e"」としてEUC-JPを指定しましたが、コマンドラインで「ruby -Ke test.rb」のように-Kオプションを指定してもOKです。 *2

Ruby 1.9の場合

しかしですね、文字コード周りが大幅に強化されたRuby 1.9ならきっともっとスマートになんとかしてくれるはず…! サポートされるエンコーディングもこんなにあります

さて、Ruby 1.9では$KCODEが廃止されて、「ソースコードに日本語を使うときはマジックコメントを書いてください」というポリシーになりました。例えば

 # coding: utf-8
 puts "日本語"

のように。1行目がshebang(#!)のときは2行目に書きます。前後に余計な文字があっても良いので、Emacs使いなら

 # -*- coding: euc-jp -*-

と書くのが良いでしょう。また「:」の代わりに「=」でも良いらしいので、vim使いなら

 # vim:set fileencoding=euc-jp:

と書くことができます。

よってスクリプトに「coding: iso-2022-jp」と書いておけば解決…と言いたいところなのですが、Ruby1.9でもJISコードはダミーエンコーディング*3なのでスクリプトのエンコーディングとしては使用できません。

でも大丈夫、1.9ではFile.openのモード指定("r"とか"w"とか書くところね)に文字コードの情報も書けるようになったので、 「これはJISコードだよ」と宣言しつつ読み出せばいいはずです。

str = "footestbar"
after = File.read("tasuan.jis", mode: "rb:iso-2022-jp").chomp
puts str.gsub(/test/, after)
open1.rb:3:in `gsub': incompatible character encodings: ISO-2022-JP and US-ASCII (Encoding::CompatibilityError)
        from open1.rb:3:in `<main>'

おっと、afterがJISコードならstrもJISコードにしなければならないようです。

str = "footestbar".encode("iso-2022-jp")
after = File.read("tasuan.jis", mode: "rb:iso-2022-jp").chomp
puts str.gsub(/test/, after)
open2.rb:3:in `gsub': incompatible encoding regexp match (US-ASCII regexp with ISO-2022-JP string) (ArgumentError)
        from open2.rb:3:in `<main>'

そうか正規表現もか。

しかしRegexp#encodeというメソッドはないぞ…。エンコーディングを付加した文字列を正規表現に変換すればいいのかな。

str = "footestbar".encode("iso-2022-jp")
pattern = Regexp.new("test".encode("iso-2022-jp"))
after = File.read("tasuan.jis", mode: "rb:iso-2022-jp").chomp
puts str.gsub(pattern, after)

これでどうだろう?実行してみる。

foo!testEbar

駄目じゃん/(^o^)\

はっ!よく見たらリファレンスにこんなことが…

ダミーエンコーディング

文字の列としての処理をサポートしません。

[多言語化より引用]

文字の列としての処理をサポートしない→単純にバイトの列としてgsubされる→おおこれは\0だな→testに置き換えるか→文字列が壊れる

結論

例えばiso-2022-jpを避ける

str = "footestbar"
after = File.read("tasuan.jis", mode: "rb:iso-2022-jp").chomp.encode("utf-8")
puts str.gsub(/test/, after)

実行結果:

/Users/yhara/proj/blog/plus_kurai % ruby-1.9 conv.rb
foo+暗bar

Ruby 1.9はべんりですね (^o^)

参考

「Rubyリファレンスマニュアル刷新計画」のm17nの項が非常に参考になりました。

*1 ってJIS以外でが出てくるパターンあるのか?

*2 ただしソースコード中に漢字が入ってる場合はコマンドラインオプションの方を使わないと駄目。実行時には既にソースコードを読み終わってるわけなので、その後で$KCODEを設定しても遅いw SJISで、2バイト目に「\」が来るような漢字が文字列リテラルに入ってるときとかに問題になるやつですね

*3 「Ruby が名前を知っているが、 文字の列としての処理に対応していないエンコーディング」だそうな

[ruby] 1.9.1-preview1でのダミーエンコーディングの一覧

上の記事のおまけ。

irb(main):009:0> Encoding.constants.find_all{|c| e=Encoding.const_get(c); e.respond_to?(:dummy?) and e.dummy?}
=> [:ISO_2022_JP, :ISO2022_JP, :ISO_2022_JP_2, :ISO2022_JP2, :UTF_7, :CP65000]

[ruby] irb-1.9

上のテストはirb-1.9を利用しました。irb-1.9は僕が自分で書いているシェルスクリプトで、中身は

#!/bin/sh
ruby-1.9.1-preview1 -rirb -e 'IRB.start'

のようになっています。ruby-1.9.1-preview1はhomeにインストールしたruby 1.9へのsymlinkです。

「1.9を使ってみたいけど、/usr/local/binにインストールする勇気はない(もしくは1.8と共存したい)」という人におすすめです。

本日のツッコミ(全5件) [ツッコミを入れる]
ひがき (2008-11-02 10:00)

私は 1.9 の configure 時に --program-suffix=19 を付けて 1.8 と共存させています。

no6v (2008-11-02 12:41)

gは僕が自分で書いているエイリアスで、中身は<br>alias g='goruby -rirb -e IR.st'<br>のようになっています。<br>En.l.se(&:y).m(&:ns).fl<br>結果が文字列の配列だけど :-)。

yhara (2008-11-02 13:25)

ひがきさん:<br>http://shinh.skr.jp/m/?date=20081102#p03 でも突っ込まれました。ありがとうございます。<br>no6vさん:<br>gorubyにそんな使い方が!僕も導入してみます。

ku-ma-me (2008-11-03 01:42)

今のところ<br>File.read("tasuan.jis", mode:"rb:iso-2022-jp:utf-8")<br>とも書けるようです。リリース時にどうなるかはわかりませんけど (笑)

yhara (2008-11-03 13:55)

おお、.encode()が不要になるわけですね。便利そうだなぁ。