2003 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 10 | 11 | 12 | 2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 | 2011 | 03 | 04 | 05 | 06 | 07 | 09 | 10 | 11 | 12 | 2012 | 01 | |
2012-01-15(日)
■[Comp]Galaxy SIIでの音楽ファイルの文字化け対応

結局、ID3タグの文字コードをUnicodeにしておけば大丈夫なようで、iTunesでのリッピング後にツールで変換する。
ツールとしては、フォルダのドラッグ&ドロップで一括変換*1できるこれを使った。最初からiTunesでUnicodeにしてくれれば良いのに。
「ID3Uni」 http://www.vector.co.jp/soft/winnt/art/se318387.html
購入: 2人 クリック: 34回
2012-01-14(土)
■[Win]IE9のマウスジェスチャとGreasemonkey

マウスジェスチャ
Mouse Gestures for Internet Explorer http://www.ysgyfarnog.co.uk/utilities/mousegestures/
32bit用のみ。
Greasemonkey
Trixie http://www.bhelpuri.net/Trixie/
32bit用と64bit用がある。
スクリプトはscriptフォルダに手動で放り込む必要がある。
ということで、両方を使いたかったら、32bit用のIE9を使う。
2011-12-30(金)
2011-12-18(日)
■[JavaScript]無名関数の呼び出し

「JavaScriptの無名関数の実行 (function(){})() と (function(){}()) の違い」http://polygon-planet.blogspot.com/2011/12/javascript-function-function.html
を見て、なるほど。
今まで、無名関数の呼び出しは、
(function(x){alert("<<"+x+">>");})("foo");
と括弧で囲んでやっていたけど、式の文脈では、
var hoge = function(x){alert("<<"+x+">>");}("foo"); (function(x){alert("<<"+x+">>");}("foo")); +function(x){alert("<<"+x+">>");}("foo");
function(x){alert("<<"+x+">>");}("foo");
なお、JScriptだとこれはエラーにならない。どうも、無名関数定義が無駄に捨てられてから、うしろの括弧が評価されるようだ。
2011-11-07(月)
■[Ruby] 続:Mechanize2.0 ではまる

今度は mixi にログインできない。ログを見ると同じくCookieが送られていない。Mechanize 1.0.0 を使うと問題ない。今回はドメインの問題では無いので、また別の原因があると思われる。
2011-11-12 追記
原因は判明。Set-Cookie で domain=.mixi.jp のCookieが送られてくるが、これが、mixi.jp に対してのドメイン検査に引っかかって送られていない。これはバグだ。
class Mechanize::CookieJar (中略) def cookies(url) (中略) if cookie_domain.start_with?('.') url.host =~ /#{Regexp.escape cookie_domain}$/i else url.host =~ /^#{Regexp.escape cookie_domain}$/i end (後略)
これを、
class Mechanize::CookieJar (中略) def cookies(url) (中略) if cookie_domain.start_with?('.') "."+url.host =~ /#{Regexp.escape cookie_domain}$/i else url.host =~ /^#{Regexp.escape cookie_domain}$/i end (後略)
に少し修正すればOK。
キタモモンガさんのブログ*1にも、Cookieがおかしいという話が書いてあるが、これは、上記の話じゃ無くて「Mechanize2.0 ではまる」id:otn:20110924 の話だ。
2011-11-06(日)
■[Ruby]Excel列名変換問題

id:JunichiIto:20111102:1320253815 の「Excel列名変換問題で第2回社内プログラミングコンテストを開催してみた(前編)」を見て、やってみた。
Rubyで書くことにしたが、Ruby固有の機能は使わずCでも簡単に書き直せる程度で。
Excelの列名は、A,B,…,Z,AA,AB,…AZ,BA,… のようになっているが、これと番号 1,2,…,26,27,28,…,52,53,… との相互変換を行う。
まず、文字から番号は簡単。
ARGV.each do |arg| case arg when /^[A-Z]+$/ val = 0 arg.each_char do |c| val = val*26+c.ord-"@".ord end puts val end end
逆の変換は26で割っていくのだが、割る前に1始まりなので1を引く必要があるな。後で1足せば良いかということで、"@"の代わりに"A"を使う。
ARGV.each do |arg| case arg when /^[1-9][0-9]*$/ val = arg.to_i-1 ans = "" while val>0 ans = (val%26+"A".ord).chr+ans val /= 26 end puts ans end end
しかし、1 が Aでなく空になって、2〜26 は B〜Zになるものの、27 は AA じゃなくて BA になってしまう。全然だめ。
しばし考えて修正*1。
ARGV.each do |arg| case arg when /^[1-9][0-9]*$/ val = arg.to_i ans = "" while val>0 val -= 1 ans = (val%26+"A".ord).chr+ans #Ruby1.9.3でString#prependが出来たのでそれで書き直せる val /= 26 end puts ans end end
これが落とし穴か。
ARGV.each do |arg| case arg when /^[A-Z]+$/ val = 0 arg.each_char do |c| val = val*26+c.ord-"@".ord end puts val when /^[1-9][0-9]*$/ val = arg.to_i ans = "" while val>0 val -= 1 ans = (val%26+"A".ord).chr+ans val /= 26 end puts ans end end
2011-11-19 追記
何となくループで書いたけど、この手の物は再帰で書くべきだったか。関数型言語風。
def atoi(x) if x.size == 1 x.ord-"@".ord else atoi(x[0..-2])*26 + atoi(x[-1]) end end def itoa(x) if x<=26 (x+"@".ord).chr else itoa((x-1)/26) + itoa((x-1)%26+1) end end
2011-11-05(土)
■[Ruby] UTF-8で処理するがファイルにはShift_JISで書く

メモ。
文字コード変換に限らず、ファイル書き出しの直前に、処理を挟み込む場合。
# encoding: utf-8 require "nkf" # 特異メソッドを定義する方法 open("output1.txt","w") do |f| def f.write(str) super(NKF.nkf("-W --windows",str)) end f.puts "あいうえお" end # サブクラスを定義する方法 class MyFile < File def write(str) super(NKF.nkf("-W --windows",str)) end end MyFile.open("output2.txt","w") do |f| f.puts "あいうえお" end
2011-10-27(木)
■[Comp]「さくらのVPS」httpのproxyを作る

前に書いたような気がするけど、akamaiサーバーへのアクセスが遅いので、さくらのサーバーをproxyでかませてみると改善するかもしれないと、proxyサーバーを動かしてみる。
squid*1をインストールして、ポート番号を変えて、ダイジェスト認証を掛ける。目的からしてhttpのみ対応。
設定は下記。
--- squid.conf.default 2010-03-31 16:46:03.000000000 +0900 +++ squid.conf 2011-10-27 22:54:18.000000000 +0900 @@ -141,6 +141,7 @@ # Then, set this line to something like # # auth_param digest program /usr/libexec/digest_auth_pw /usr/etc/digpass +auth_param digest program /usr/lib64/squid/digest_pw_auth /etc/squid/passwd # # "children" numberofchildren # The number of authenticator processes to spawn. If you start too few @@ -566,7 +567,7 @@ #Examples: #acl macaddress arp 09:00:2b:23:45:67 #acl myexample dst_as 1241 -#acl password proxy_auth REQUIRED +acl password proxy_auth REQUIRED #acl fileupload req_mime_type -i ^multipart/form-data$ #acl javascript rep_mime_type -i ^application/x-javascript$ # @@ -634,6 +635,7 @@ # And finally deny all other access to this proxy http_access allow localhost +http_access allow password http_access deny all # TAG: http_access2 @@ -918,7 +920,7 @@ # visible on the internal address. # # Squid normally listens to port 3128 -http_port 3128 +http_port ナイショ # TAG: https_port # Usage: [ip:]port cert=certificate.pem [key=key.pem] [options...] @@ -4276,6 +4278,7 @@ # #Default: # forwarded_for on +forwarded_for off # TAG: cachemgr_passwd # Specify passwords for cachemgr operations.
*1:Version 2.6.STABLE21
2011-10-20(木)
■[Ruby] 円周率の計算をしてみる

ふと、円周率の計算をしてみる。Wikipediaの記事 wikipedia:円周率 を参考にした。簡単な式は、
だが、これは見るからに収束が遅いので、次の式を使った。
高速化を目指すと大変そうなので、安易にRationalに頼って、少数化は、倍するだけ。
def fact(n) (1..n).inject(:*) or 1 end NMAX=130 KETA=77 sum=0 (0..NMAX).each do |n| sum += Rational(6*fact(2*n),2**(4*n+1)*fact(n)**2*(2*n+1)) w = (sum*10**KETA).to_i.to_s w[1,0] = "." puts w end
2011-09-24(土)
■[Ruby] Mechanize2.0 ではまる

Mechanizeをver1からver2に上げたら、社内で使っていたスクリプトが動かなくなった。ログオン部分で引っかかり先に進めない。とりあえず、バージョン指定で旧バージョンを指定してしのいでいたのだが、「そんなに難しいことは無いだろう」と調べてみた。
定番のid:kitamomongaさんの情報サイト、http://d.hatena.ne.jp/kitamomonga/20110628/ruby_mechanize_2_0 を見るが、どうも該当しそうな記述が無い。ログをとってみると、シングルサインオン認証済キーのCookieを送っていない。関連の部分を調べてみると、あった。
Cookieを追加する Mechanize::CookieJar#add の冒頭が変更されている。
return unless valid_cookie_for_uri?(uri, cookie)
valid_cookie_for_uri?は、こういうチェックをしているが、この2つめがver1ではやってない。
# Permitted: A Set-Cookie for x.foo.com for Domain=.foo.com
# Not Permitted: A Set-Cookie for y.x.foo.com for Domain=.foo.com because
# y.x contains a dot
# Not Permitted: A Set-Cookie for foo.com for Domain=.bar.com
シングルサインオン認証のCookieは、domain=.example.com と広めに投げられているが、使いたいホスト名は、foo.intra.example.com だ! domain=.intra.example.com だったのなら問題なかったのだけど。
不許可の理由は、共用レンタルサーバーの絡みかと思ったけど、関係ないか。example.sakura.ne.jp とかから、domain=.sakura.ne.jp で投げ放題だよね。
「できるだけ狭い範囲に投げろ」という精神論か?それはサイトに言ってくれよ〜。クライアント側ではブラウザ互換にしてほしいな。
対応としては、Mechanize::CookieJar#add の上書き修正。add を呼ぶ前に domain= を書き換える手もあるか。
class Mechanize::CookieJar def add(uri, cookie) return unless uri.host =~ /#{self.class.strip_port(cookie.domain)}$/i normal_domain = cookie.domain.downcase @jar[normal_domain] ||= {} unless @jar.has_key?(normal_domain) @jar[normal_domain][cookie.path] ||= {} @jar[normal_domain][cookie.path][cookie.name] = cookie cookie end end
2011-07-30(土)
■[Ruby]Rubyは参照渡しか値渡しか?

「PHP しか書けなかった僕が Ruby を始めたころに思ったこと10点 « blog.udzura.jp」を見て、「Rubyは参照渡しか値渡しか?」という議論があるらしいことを知る。id:iox:20070203:1170506166 とか。
そもそも、そういうのは、変数に値の入る言語での区別の話で、変数には原則として参照が入るRubyでは、区別が無意味だと思う。
rubyには変数の参照というものがないので
というのは、それはそう。Rubyでの変数はオブジェクトにつけた名札なので、名札は呼び出した先のメソッドには渡らないということだね。
def foo(bar) bar="bar" end baz="baz" foo(baz) p baz #=> "baz"
ということを以て、「Rubyは値渡し」というのは、言葉を定義しなおしている感がある。つまり、「実際にわたっているのは何か」で定義するのではなく、「仮引数に代入したときに実引数の変数の内容が変更されるか」で、参照渡しと値渡しという言葉を定義しなおしている。
2011-07-18(月)
■[Comp][TV] RDレコーダーのバグに連続してやられる

東芝RD機を現在二台使っている。昨年購入のRD-X9と、今月購入のRD-BZ810。
RD-X9で、数ヶ月前から、予約録画中にハングアップするという現象がたまに出ていた。本体電源スイッチの長押しで切るしかない。再現性が弱いので、熱のせいかと思っていたのだが、最近頻度が上がってきたので、サポートセンターに電話。こちらは人間に繋がる前に、X9他数機種で録画に失敗したり操作出来なくなる現象が出ていてソフトウェア更新で対応するというアナウンスが流れたので、それを聞いて電話を切る。
RD-BZ810で、昨日から録画失敗の連続で再現性有り。DRだと録画出来るがAVCだと駄目。これは待たずにさっそく電話。こちらは人間と会話。高速起動をオフにして再起動してみてくれと。で、ソフトウェアバージョンも確認。
いずれもソフトバグでアップデートが出ていた。http://www3.toshiba.co.jp/hdd-dvd/support/index_j.html
RD-X9は、
RD-BZ810は、
[2011.7.14] ソフトウェア・バージョン03をリリースしました。
RD-X9の方は、現象が出てすぐに電話で聞いていれば、まだソフト改修が出来ていないので、いろいろやりとりが大変だったかも。不幸中の幸い?
2011-07-16(土)
■[Comp] Galaxy+Android2.3 の音楽ファイル管理機能バグに困っている人を助けてくれるツール「MediaFix」

iPhoneからGalaxy SIIに切り替えて、いくつか困ったことがあるが、まずはこれ。
iTunesでAACでリッピングした曲を転送すると、アーティスト名が認識されず、すべて「Unknown Artists」「不明なアーティスト」になってしまう。
標準添付のもの含め、いくつかプレーヤーソフトを試したが全滅。
ググると、どうもGalaxy with Android2.3の不具合らしい。さらにググって、修正ツールを発見した。起動するだけでファイルを修正してくれる。
http://androrank.com/?id=eu.gorgonloop.MediaFix&m=upd
2011-06-02(木)
■[一般] 歴史クイズ

高校レベルの歴史の問題です。次のA〜Eに入る人名または地名を答えなさい。
[A] は、中国([B])の征服のために [C] に軍団を与えて遣わした。その後、[A] は自ら [B] の征服に参加するために出陣したが、途中で急死してしまった。その死を知った [C] は、急遽、都である [D] に向けて引き返し、[A] の後継者として [D] 周辺を支配し始めていた [E] を戦って破り、名実ともに [A] の後継者の地位に就いた。
正解は、下記を範囲選択するか、ctrl-A を押してください。
A: モンケ
B: 南宋
C: フビライ|クビライ
D: カラコルム
E: アリクブケ|アリクブカ
正解出来ましたか?
2011-05-20(金)
■[Ruby]JSONのキーは文字列

さて、では、この Hash を JSON形式に変換してあげるとどうなるでしょうか?
require "rubygems" if(RUBY_VERSION < '1.9.1') require "json" test4hash = {nil => "nil!", "" => "empty!"} p test4hash.to_json # => "{\"\":\"nil!\",\"\":\"empty!\"}"ふむふむ。
これを Parse するとどうなるでしょう?
require "rubygems" if(RUBY_VERSION < '1.9.1') require "json" test4hash = {nil => "nil!", "" => "empty!"} p JSON.parse(test4hash.to_json) # => "{\"\"=>\"empty!\"}"
これの原因としては、
ということからでしょうか。
同じ事は、{1=>"one","1"=>"ichi"} 等でも起こる。
キーに文字列以外が使われているHashを to_json するとエラーになるという仕様にすれば防げるけど、使いにくくてしょうがない気がする。
JSONでも値の方は、null も使えるので、これはRuby側では nil にマッピングされてますね。
そう言えば、nil.to_s を "" でなく "nil" にする案もあったようだ。"" との衝突の問題が、"nil" との衝突の問題に変わるだけで、上記の問題の解決にはならないが。
2011-05-03(火)
■[Comp]「さくらのVPS」bash-completion インストール

id:otn:20110501 で書いた通り、CentOSにはbash-completionパッケージ*1が含まれていない。Fedoraでこれに慣れていると無しではいられないので、インストールする。
Fedoraプロジェクトが、RHELやCentOS向けに提供しているEPEL*2ライブラリに無いか探してみる。yum のリポジトリに追加してしまうと、今後、意図せず標準でないパッケージをインストールしてしまう可能性があるので、それはしない。
EPEL/ja - FedoraProject の、「利用可能なパッケージ: 」欄の EPEL5 の x86_64 のページを開いて探すと、System Tools の中にあった。これをインストール
# rpm -ivh http://download.fedora.redhat.com/pub/epel/5/x86_64/bash-completion-1.2-4.el5.2.noarch.rpm
2011-05-02(月)
■[Comp]「さくらのVPS」ファイアーウォール設定

iptablesについて調べて*1設定してみた。初期設定ではiptablesプロセスは起動するが全部通しになっている。
方針は、
設定する方法として、
の二通りの方法があるようだが、コマンドは面倒なので後者のやり方で。
*filter # INPUTチェーンのデフォルトは条件に合わない物は後でDROPするのでどっちでも良いがDROPと書いておく :INPUT DROP [0:0] # 中継はDROP :FORWARD DROP [0:0] # OUTPUTチェーンのデフォルトはACCEPT :OUTPUT ACCEPT [0:0] # ログに書いてDROPするというユーザー定義チェーンを作る :DROPLOG - [0:0] ##### 入力パケットについて # loopbackからはACCEPT -A INPUT -i lo -j ACCEPT # ICMPはとりあえずACCEPTにしておく。やっぱり止めるかも -A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT # 通信途中の物はACCEPT -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT # 開始パケットはsshとhttpとsmtpはACCEPT。sshのポート番号は22でなく変更した物を書く -A INPUT -p tcp -m state --state NEW -m tcp --dport sshポートの番号 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT -A INPUT -p tcp -m state --state NEW -m tcp --dport 25 -j ACCEPT # それ以外の物はログに書いてDROP -A INPUT -j DROPLOG ##### 出力パケットについて # ブロードキャストはログに書いてDROP -A OUTPUT -d 255.255.255.255 -j DROPLOG -A OUTPUT -d 自分のサブネットのブロードキャストアドレス -j DROPLOG ##### ユーザー定義チェーンの内容 # ログに書くのは1時間に3件まで。メッセージ先頭に目印を付ける -A DROPLOG -m limit --limit 3/hour -j LOG --log-prefix "DROP:" # ログを書いた後DROP -A DROPLOG -j DROP # 反映する COMMIT
# iptables-restore < /root/iptables
この状態で一通りテストする。間違えてsshセッションが切れた場合は、管理パネルのコンソールからリブートすれば元に戻る。
問題がなければ、起動時に読み込む設定ファイルに書き込む。これで次回起動からも設定が生きる。
# iptables-save > /etc/sysconfig/iptables
Dropbox攻撃
ログを見てみると、そばのサーバーから17500ポートへUDPパケットが30秒ごとに2つずつ来ている。
ググルと、Dropbox のオプションによりそうなるようだ。
xx.xx.xx.xx から 30秒ごとに2回、ポート 17500 にUDPでブロードキャストが来ます。
========================================
xx.xx.xx.xx の管理者殿
あなたのサーバーから周りの他のサーバーに大量の無駄なネットワーク通信が行われています。
通信内容から、Dropboxの設定で「Enable LAN sync」をオンにしていると思われますが、そのオプションは、同一LAN内の他のコンピューター上のDropboxと同期するための物です。
「あなたが xx.xx.xx.xx と同じLANに別のサーバーを借りていて両方のサーバーでDropboxを動かしていて、その間で同期をしたい」
2011-05-01(日)
■[Comp]「さくらのVPS」いろいろ初期設定

管理者パスワード変更
コントロールパネルのパスワードと、初期設定OSのrootパスワードは同じだが、当然のことながら連動していないので、それぞれ変更。普段手で打ち込むことはないので、長い文字列にしておく。
一般ユーザを作る
# useradd ユーザ名 # passwd ユーザ名 # usermod -G wheel ユーザ名 # visudo で、"%wheel ALL=(ALL) NOPASSWD: ALL" の行を有効にする(パスワード無しでsudoできるよう)
ssh設定
1. とりあえずTeratermを使って一般ユーザでパスワードでログイン
2. Teratermの設定>ssh鍵生成で、RSAにチェックして生成ボタンを
3. パスフレーズを適当に入れて、公開鍵(id_rsa.pub)と秘密鍵(id_rsa)をTeratermフォルダに保存
4. 専用接続用にTeratermのショートカットを作る。リンク先は、
"C:\Program Files\teraterm\ttermpro.exe" ssh://ユーザ名:パスフレーズ@IPアドレス:ポート番号 /auth=publickey /keyfile=id_rsa
5. Linux側で
$ mkdir ~/.ssh $ chmod 700 ~/.ssh $ vi ~/.ssh/authorized_keys 公開鍵ファイルの中身をコピペ。 $ chmod 600 ~/.ssh/authorized_keys
6. 一旦、ポート番号22で公開鍵でログイン出来ることを確認
7. /etc/ssh/ssh_configを修正してパスワードログインを不可に等
・・・ #Port 22 =====>の下に Port ポート番号 ・・・ #PermitRootLogin yes =====>の下に PermitRootLogin no ・・・ PasswordAuthentication yes =====>の行を変更 PasswordAuthentication no ・・・
8. コンソールからsshdを再起動(service sshd restart)
いろいろインストール
1. まずは yum update =====> Kernel含めていろいろアップデートされる
3. yum install bash-completion =====> 無い! yum list をみたけど無さそう。別途 rpm からインストール
4. yum install vim-common vim-enhanced
5. yum install "php53*" <===== PHPは、5.1.6 と 5.3.3 がある
6. yum install readline-devel mysql-devel openssl-devel sqlite-devel <===== RubyやGemsのインストールに備えて
7. Ruby1.9.2をソースからインストール <===== yum でインストール出来るのは 1.8.5 !!
いろいろ設定
・/etc/sysconfig/i18nを修正
LANG="ja_JP.UTF-8"
・/etc/profile.d/local.shを作成
alias m=less alias ls="ls -xvF" alias vi=vim alias eman="LANG=C man" bind "\C-p:history-search-backward" bind "\C-n:history-search-forward" HISTSIZE=9999 HISTIGNORE="&: *" #直前の行と同じor行頭が空白の場合はヒストリに残さない export HISTTIMEFORMAT="%m-%d %T " shopt -s histappend #.historyファイルに追加書き export LC_TIME=C #日付書式は英文で addpath(){ local w eval w=\$$1 case ":$w:" in *:$2:*) ;; *) export $1="${w}${w:+:}$2" ;; esac } addpath LD_LIBRARY_PATH /usr/local/lib
・/etc/inputrc の末尾に追加
"\C-n":history-search-forward "\C-p":history-search-backward
・/etc/screenrc の末尾に追加
escape ^z^z vbell_msg ""
・/root/.gemrc を作成(Rubygems用)
gem: --no-ri --no-rdoc
2011-04-30(土)
■[Comp]「さくらのレンタルサーバー」から「さくらのVPS」への移行

連休だし何かやるかと言うことで、VPSへの移行を考える。料金はレンタルサーバースタンダードが年間5000円で、VPS メモリ512MBのプランが10780円と約2倍だが、年間5000円の追加だからまあいいかと。これで、自分の自由になるサーバーがインターネット側に持てることになる。ある程度の平行期間を想定。
最初の問題は何かというと、メールアドレスだ。レンタルサーバープランだと、さくらの持っているドメインのサブドメインを2つまで自分で選んで付けられるので、そのメールアドレス(短い)をあちこちで使っていたのだ。
各種アカウントや会員登録のメモを頼りに、GmailかGoogleAppsのメールアドレスへの変更を十数個やる。いくつかはもう使っていないのでこれを機会に退会する。ここ数ヶ月に届いたメールを検索してみて、漏れは無さそう。
1つ、メーリングリストに使っているアドレスがあるのだがこれはそのうち案内することにして、後回し。
2011-03-02(水)
■[Ruby] Windows用 Ruby1.8 で json 1.5.1 を使う場合のエラーダイアログについて

「ActiveScriptRuby 1.8.7 を利用している環境で json 1.5.1-mswin32 を使うと、msvcrt-ruby191.dll を呼びに行こうとして失敗する問題」g:fragile:id:ferricks:20110130
「Ruby 1.8.7とjson1.5.1 x86-mswin32で、「msvcrt-ruby191.dllが見つからない」エラー」id:MonteCut:20110219
等で書かれているように、mswin32版 Ruby1.8.7 で json 1.5.1 を自然にインストールして require "json" すると、msvcrt-ruby191.dll がないというエラーダイアログが出る。RubyInstaller のような mingw32版でも同じだ。
対策方法は4つあり*1、
1 は上記記事にあるので省略。
2 は、http://www.garbagecollect.jp/ruby/mswin32/ja/download/release.html から、zipファイルをダウンロードしてそこからmsvcrt-ruby191.dllだけ取りだして、ruby\bin とかに入れておく。
3 はビルド環境を予め作っておく必要があるが、今後も何かと便利なのでお勧め。mswin32の環境を作るのはVisual Studio Expressのインストールになるのだろうが、普段VC++でプログラムしない人にはなんだか牛刀だし、gemから自動起動するように環境設定するのも面倒かもしれない(やったことはないので実は簡単なのかも)。
バイナリ互換のmingw32版だとRubyInstallerのDevKitを使える。http://rubyinstaller.org/downloads/ から Development Kit をダウンロードして解凍し、下記を実行。実はmswin32環境では確認してないが、ディレクトリ構成は同じはずなので dk.rb install でうまくいくんじゃないかな。
C:\解凍先> dk.rb init (config.ymlが出来るので内容を確認し必要なら修正) C:\解凍先> dk.rb install
RubyInstallerを使っている人はレジストリを見て自動的にconfig.ymlが作られるが、そうでない人やmswin32版を使っている人はレジストリにエントリがないのでコメントだけのconfig.ymlが作られる。その場合、コメントに習って、
--- - C:/Ruby
の様に、RubyのインストールディレクトリをYAML形式で書いておく。
C:\HOME> gem install json --platform ruby Fetching: json-1.5.1.gem (100%) Temporarily enhancing PATH to include DevKit... Building native extensions. This could take a while... Successfully installed json-1.5.1 1 gem installed
でソースからバイナリ generator.so と parser.so が作られる*2。
さて、一番簡単なのは 4 だ。Rubyのバージョンが1.8.7なので、実際に msvcrt-ruby191.dll 内のモジュールが呼ばれることはない。require の時のエラーダイアログだけ気にしなければ、あとは普通に動く(はず)。
2010-12-24(金)
2010-11-28(日)
■[Comp]2種類の浮動小数点形式 IEEE754とPDP

そこらへんの/usr/include/float.hにある浮動小数点データの指数の最大値・最小値は、単精度だとこうなっている。
#define FLT_MIN_EXP (-125) #define FLT_MAX_EXP 128
何故正と負でこんなに差があるのかという解説*1。
理由を一言で言うと、「Cの浮動小数点モデルはPDPの浮動小数点形式に由来するが、実際に動いているCPUはIEEE754に従った浮動小数点形式を処理するから」である。
どちらの形式も、単精度32ビットの内訳は、符号1ビット、指数部8ビット、仮数部23ビットであるが、指数部と仮数部の意味づけが異なる。
異なるのは、仮数部をどのように正規化するかで、IEEE754では1以上2未満にするが、PDPだと0.5以上1未満になる。実際の仮数部表現では最上位の1のビットを省略するところは同じなので、有効数値桁はどちらも23ビット全体。他にも指数部の下駄がIEEE754だと127、PDPは128と異なるが今回の話とは関係ない。
Cの規格書の「5.2.4.2.2 Characteristics of floating types <float.h>」をみると、仮数部は0.5以上1未満になることがわかる。浮動小数点数を仮数部と指数部に分解する関数frexpで得られる仮数部も実際にその範囲になっている。つまり、CはPDP型の浮動小数点形式をベースにしている。UnixがPDP上で誕生したという経緯があり、過去からの互換性を守るためであろう。
本題に戻って、実際にIEEE754で使える仮数部は00000000は±0か非正規化数、11111111は±∞か非数なので、00000001から11111110であり、下駄が127なので-126から+127になる。仮数部1で指数が-126〜+127というのを、仮数部0.5にすると指数は-125〜+128になり、冒頭の結果となる。
2010-11-08(月)
■[Ruby] Rubyでcall by nameっぽいこと

Algol60の引数機構であるcall by nameは今ではすっかり廃れて若い人には知られていないと思われるが、一言で言うと「クロージャを引数に渡す」ということで、クロージャの表記が非常にコンパクト。変数や式がそのままクロージャになる。
VALUE指定のfromとtoがcall by valueで、それ以外のsumとvarとexprの引数がcall by name。
BEGIN INTEGER m,n; PROCEDURE sub(sum, var, expr, from, to); VALUE from, to; INTEGER sum, var, expr, from, to; BEGIN sum := 0; FOR var := from STEP 1 UNTIL to DO sum := sum + expr; END; sub(m, n, n*n, 1, 10); print(m); END
少し解説すると、subでsumに代入すると実引数であるmへの代入となる。varへの代入も同じくnへの代入となる。これだけならcall by referenceでも同じだ。違うのは、exprを評価すると、その時点で呼び出し側環境でn*nを評価してその結果を値とする。つまりn*nがクロージャとしてsubにexprという名前で渡ったことになる。
call by name の代わりに、値をセットするクロージャと値をゲットするクロージャのペアを渡す。式に対しての値のセットはエラーにする。
def sub(setsum,getsum,setvar,getvar,setexpr,getexpr,from,to) setsum[0] for i in from..to setvar[i] setsum[ getsum[] + getexpr[] ] end end m=nil n=nil sub( lambda{|x| m=x}, lambda{m}, lambda{|x| n=x}, lambda{n}, lambda{raise "bad use"}, lambda{ n*n }, 1, 10 ) puts m
うーん、これは手で書く気がしない。
2010-10-30(土)
■[Comp] ThinkPad ファン交換

3年半使っているThinkPad T60だが、ファンの異音がひどくなってきたので、交換した。全体の流れはこんな感じ。
- 保守マニュアルをダウンロードして部品型番を調べる
- http://aichi.to/~thinkpad/part.html のページを参考にして電話で注文用紙取り寄せ(FAX)
- 代金+送料振り込み
- 注文用紙と振り込み控えをFAXして注文
- 保守マニュアルによるとグリスも必要なので購入。グリス除去用アルコールも
- 部品到着
- 保守マニュアルを見ながら開腹して交換
保守マニュアルを見ると、「ファンおよびサーマルデバイス」は本体型番によって違い、数種類ある。マニュアルには標準モデルの本体型番しか書いてない。カスタマイズモデルの場合は該当する標準モデルの型番で調べることになるのでいろいりLenovoサイトページを見てそれらしい型番を発見。しかし数千円する物なので、念のため一度分解して部品に書いてある型番を調べることにした。予想通りの型番で安心。
交換は問題なしだが、グリスを塗るべきサーマルデバイスのCPU接触部分に最初からグリスらしい物が少しだけ付いている。少し迷ったが少しだけ追加することに。0.2g付けることになっていたが、最初の量だと少し少ない気がしたので。まあ、押さえつけて広げれば大丈夫だろうということで。
2010-10-28(木)
■[Comp]ミリタリータイムゾーン

タイムゾーンというと、+0900 のように符号と四桁の数字か、UTC PST JST のような三文字の英字*1、Asia/Tokyo のようなzoneinfoのファイル名とかで表すが、米軍規格の一文字英字もある。UTC を一文字で Z で表すのはここから来ている。ちなみに JST は V だ。
export TZ=UTC for T in A B C D E F G H I J K L M N O P Q R S T U V W X Y Z JST PST do date "+$T %Y-%m-%d %H:%M" -d "2010-01-01 00:00:00 $T" done
実行結果、つまり「各タイムゾーンの午前0時がUTCで何時になるか」は、
A 2010-01-01 01:00 B 2010-01-01 02:00 C 2010-01-01 03:00 D 2010-01-01 04:00 E 2010-01-01 05:00 F 2010-01-01 06:00 G 2010-01-01 07:00 H 2010-01-01 08:00 I 2010-01-01 09:00 date: invalid date `2010-01-01 00:00:00 J' K 2010-01-01 10:00 L 2010-01-01 11:00 M 2010-01-01 12:00 N 2009-12-31 23:00 O 2009-12-31 22:00 P 2009-12-31 21:00 Q 2009-12-31 20:00 R 2009-12-31 19:00 S 2009-12-31 18:00 T 2009-12-31 17:00 U 2009-12-31 16:00 V 2009-12-31 15:00 W 2009-12-31 14:00 X 2009-12-31 13:00 Y 2009-12-31 12:00 Z 2010-01-01 00:00 JST 2009-12-31 15:00 PST 2010-01-01 08:00
面白いのは、どちらか方向に一周するのでなく、西半球を半周してから東半球の半周に戻ることと、飛ばしているのがIとかOじゃなくてJなこと。
2010-10-12(火)
■[一般]ヨドバシカードも分離。Sony提携カードが全部廃止に

id:otn:20091102 に「ソニーファイナンス提携カードがほとんど終了」というのを書いたけど、唯一残っていた提携カード「ヨドバシカード」がヨドバシ100%子会社に移管という連絡が来た。9月に公表されてたみたい。
移管後もSonyファイナンスに業務委託すると言うことなので、利用者からはあまり変わらない(一部サービスが廃止)。
ヨドバシカードってそれなりにユーザもいてメインカードにしている人も少なからずだと思うんですが。残るカードはソニーカードだけだけど、今時年会費有料カードだけでやっていけるのか?ソニーカードに年会費1312円払って使い続ける利用者層がイメージ出来ない。ソニーストアでたくさん買い物する人?
2010-09-09(木)
■[本] ジェットモグラ!!(リモコン式プラモ)

昔作りました。ちなみに、ドリルでは砂場の砂も掘れません。中に砂が入ります。
VOL.0はサンダーバード二号、VOL.2は科学特捜隊のビートル号です。
大人のプラモランド VOL.1 リモコン・ジェットモグラ (ロマンアルバム)
- 作者: COMICリュウ編集部
- 出版社/メーカー: 徳間書店
- 発売日: 2010/08/03
- メディア: ムック
- 購入: 1人 クリック: 6回
- この商品を含むブログ (3件) を見る
2010-08-28(土)
■[Ruby][Win] RubyInstallerのreadlineライブラリ差し替え

RubyInstaller http://rubyinstaller.org/ で、インストールしたRuby1.8.7でirbを使うと、行編集がちょっと我慢できないくらい遅い。どうもRubyで書かれたreadline.rb/rbreadline.rbが使われているみたい。
しょうがないので、mswin32版からライブラリをコピーしてみると、うまくいった。
readline.so をライブラリパスの通ったところへ 及び readline.dll をPATHの通ったところへ。
デフォルトだと$LOAD_PATHの先頭は、lib/ruby/site_ruby/1.8 だが、ここにreadline.rbがあり、readline.soを入れても.rbの方が読まれるようだ。.soが優先だと思ってたけど。従って、readline.rbを削除するか、$LOAD_PATHの先頭に環境変数RUBYLIBなどで優先されるディレクトリを追加してそこに入れるか。
readline.dll の入手先は、http://jarp.does.notwork.org/ の "Porting Libraries to Win32" から。
2010-08-02(月)
■[Win] フォルダのアイコン変更方法

フォルダのアイコン変更方法は、書くまでもなく、プロパティのカスタマイズタブから出来るわけだが、これで出来るDesktop.ini を別のフォルダにコピーしてもそのフォルダのアイコンに変化は無い。何が違うのか?GUIでなくスクリプトでこの操作をしたいときはどうすればいいのか?
コマンドプロンプトから、attrib /s /d コマンドでアイコンを変更したフォルダの属性と、変更されていないフォルダの属性を比べてみると、変更した方は読み取り専用属性がセットされていることがわかった。
C:\temp>attrib /s /d SH C:\temp\A\Desktop.ini R C:\temp\A
Desktop.ini をコピーしたフォルダの属性を attrib +r コマンドで変更してみると、一瞬ののちにフォルダアイコンが変化する!
いろいろやってみてわかった結果のまとめ
- プロパティのカスタマイズタブでフォルダアイコンを変更すると、フォルダに「読み取り専用属性」がセットされDesktop.iniファイル(システムファイル属性、隠し属性)が出来てその中にアイコン画像の情報が書かれる
- 同じ方法で「規定値に戻す」を行っても、フォルダの属性はそのままで、Desktop.iniも削除されない。中身のアイコン画像情報が削除されるだけ
- Desktop.iniを所定の書式で作成して、フォルダの「読み取り専用属性」をattribコマンドでセットするとフォルダアイコンが変化する
- どちらかの方法でフォルダアイコンを変更した後で、Desktop.iniのアイコン画像情報を書き換えてもその時点ではフォルダアイコンは変化しない
- そのフォルダアイコン情報を反映させるにはそのフォルダを一度別フォルダに移動するか、「読み取り専用属性」をリセットしてセットし直す
- フォルダプロパティの「読み取り専用属性」のチェックボックスをチェックして適用してもフォルダの「読み取り専用属性」は変化しない。つまりExploreでは「読み取り専用属性」をセットできない。リセットも出来ない
- SysInternalsのfilemon*1で、ExplorerがどういうケースでDesktop.iniを見に行くのか調べると、フォルダが「読み取り専用属性」もしくは「システムファイル属性」を持つときである
関係ないが、filemon出力を見ていて気づいたこと
Expoloreでフォルダを表示すると、どこであろうかそこにDropboxがアクセスに行く。同期対象フォルダ以外に用はないはずなのに、何故だ?



