こせきの技術日記

2006-12-04

[][] 実行中のスクリプトが置かれたディレクトリを取得する

PerlはFindBinモジュールを使う。Rubyは__FILE__を使って取得する。

# perl
use FindBin qw($Bin);

# ruby
dir = File.dirname(__FILE__)
dir = File.expand_path(__FILE__)

2006-09-26

[][][] Cygwinrubyを入れた状態でRadRailsプロジェクトをチェックアウトしようとするとno such file to loadエラー

-e:3:in `load': no such file to load -- C:\cygwin\usr\local\bin\rails (LoadError)
	from -e:3

パスを/cygwin/usr/local/bin/railsに直したら動いた。一応rake/mong_relも同様にパススラッシュに修正。

2006-09-25

[][] 再帰的に番号の付いたディレクトリを作成

rubyの練習中なのでrubyで。

#! /usr/bin/ruby

def rmkdir(path, list)
  return if list == nil
  list[0].to_i.times do |i|
    p = "#{path}/#{i}"
    Dir::mkdir(p);
    rmkdir(p, list[1..-1])
  end
end

rmkdir(".", ARGV)
$ rmkdir.rb 10 10 10

で、./0/0/0から./9/9/9までディレクトリを作成します。

2006-09-01

[] ActionMailerで送ったメールApache Jamesでイコール記号の後ろだけ化ける

  • JamesはContent-Transfer-Encodingを明示的に指定しないと、quoted-printableに勝手に変換してくれる。ように見える。下のPerlスクリプト実験した。
    • → 全てのメールで発生するわけではなく、受信したメールを特定のインボックスに転送した場合に発生するみたい。
    • この時、イコール記号が=3Dに変換されず、単独のイコールのまま表示される場合がある。
    • 後ろの2文字を巻き込んで文字化けする。
  • ActionMailerは、明示的に指定しないとContent-Transfer-Encodingをヘッダに含めてくれない。

http://api.rubyonrails.org/classes/ActionMailer/Base.html のヘッダ指定を使って、Content-Transfer-Encodingを7bitに設定して解決した。

 class Notifier < ActionMailer::Base
   def signup_notification(recipient)
     recipients recipient.email_address_with_name
     from       "system@example.com"
     subject    "New account information"
     body       "account" => recipient
     headers    "Content-Transfer-Encoding" => "7bit"
   end
 end

みたいな感じ。

Jamesの方はコードを追ってみたけど、まだよくわからない。Java Mailのエンコードではそのような問題はおこらない。

import java.io.*;
import javax.mail.internet.MimeUtility;

public class Test {
    public static void main(String[] args) throws Exception {
        String sample = "あいうえお\n\nabc=12345";

        ByteArrayOutputStream os1 = new ByteArrayOutputStream();

        OutputStream os2 = MimeUtility.encode(os1, "quoted-printable");

        os2.write(sample.getBytes("ISO-2022-JP"));
        
        System.out.println(os1.toString("ISO-8859-1"));
    }
}

以下が出力。

$ java -classpath '.;mail-1.3.1.jar' Test
=1B$Bea$e!dea!)ea0e!j=1B(B

abc=3D12345

イコールもちゃんとエンコードしてる。

あーでもよくみたら「あいうえお」のエンコードが変だ。

=1B$B$"$$$&$($*=1B(B

のはず。

→ コンパイル時にソースコードのエンコーディング指定が抜けてるだけだった。javac -encoding UTF-8でコンパイルし直したら直った。

$ java -classpath '.;mail-1.3.1.jar' Test
=1B$B$"$$$&$($*=1B(B

abc=3D12345

2006-08-28

[][] Cygwin RubyのIconvでNo such file or directory - iconv

CygwinRubyで、

tmp.rb:5:in `iconv': No such file or directory - iconv (Errno::ENOENT)
        from tmp.rb:5

みたいなエラーが出る。困る。

検索すると、いくつか記事が見つかる。本当はIllegalSequenceが出るはずのところで、このエラーが出てるみたい。

2003~2006まで。ずっとこうなの?何か原因があるのかなー。

記事にあるサンプルを試した。ISO8859-1がinvalid encodingになったので、ISO-8859-1にしたら再現。

irb(main):001:0> require 'iconv'
=> true
irb(main):002:0> p Iconv.iconv("ISO8859-1", "UTF-8", "ABCDE")
Iconv::InvalidEncoding: invalid encoding ("ISO8859-1", "UTF-8")
        from (irb):2:in `iconv'
        from (irb):2
irb(main):003:0> p Iconv.iconv("ISO-8859-1", "UTF-8", "ABCDE")
["ABCDE"]
=> nil
irb(main):004:0> p Iconv.iconv("ISO-8859-1", "UTF-8", "\342\200\234")
Errno::ENOENT: No such file or directory - iconv
        from (irb):4:in `iconv'
        from (irb):4
irb(main):005:0>

もう1つ。

irb(main):001:0> require 'iconv'
=> true
irb(main):002:0> A_EUC="\244\242"
=> "\244\242"
irb(main):003:0> ic = Iconv.new('US-ASCII', 'EUC-JP')
=> #<Iconv:0x100b0578>
irb(main):004:0> ic.iconv(A_EUC)
Errno::ENOENT: No such file or directory - iconv
        from (irb):4:in `iconv'
        from (irb):4
irb(main):005:0> [RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM]
=> ["1.8.4", "2005-12-24", "i386-cygwin"]

linuxだとこう。ちゃんとIllegalSequenceが出てる。

irb(main):001:0> require 'iconv'
=> true
irb(main):002:0> A_EUC="\244\242"
=> "\244\242"
irb(main):003:0> ic = Iconv.new('US-ASCII', 'EUC-JP')
=> #<Iconv:0xb7f21d94>
irb(main):004:0> ic.iconv(A_EUC)
Iconv::IllegalSequence: "\244\242"
        from (irb):4:in `iconv'
        from (irb):4
        from :0
irb(main):005:0> [RUBY_VERSION, RUBY_RELEASE_DATE, RUBY_PLATFORM]
=> ["1.8.4", "2005-12-24", "i386-linux"]

仕方ないのでnkfに切り替えることにする。


(追記) ActionMailer内のTMailでエラーになってて、これをnkfに変えるのはちょっと辛い。

の82行目

          text ? Iconv.iconv(to, from, text).first : ""

で、No such file or directory。どうせcygwinは開発環境だし、いい加減もううんざりなので、直下のrescueに例外を足して誤魔化した。

        rescue Iconv::IllegalSequence, Errno::EINVAL
↓
        rescue Iconv::IllegalSequence, Errno::EINVAL, Errno::ENOENT

(追記) 解決。古いcygwinバイナリーを使うのを止めて、最新のをコンパイルして入れたら直った。

$ ruby --version
ruby 1.8.5 (2006-12-04 patchlevel 2) [i386-cygwin]