2012-04-29

The provided compiler '/usr/bin/gcc' is LLVM based, it is not yet fully supported by ruby and gems, please read `rvm requirements`.

Mac OS X Lion上でOctopressを試してみようとしたところrvm installが失敗していました。

nissuk% rvm install ruby-1.9.2-p320
Fetching yaml-0.1.4.tar.gz to /Users/nissuk/.rvm/archives
Extracting yaml-0.1.4.tar.gz to /Users/nissuk/.rvm/src
Configuring yaml in /Users/nissuk/.rvm/src/yaml-0.1.4.
Compiling yaml in /Users/nissuk/.rvm/src/yaml-0.1.4.
Installing yaml to /Users/nissuk/.rvm/usr
The provided compiler '/usr/bin/gcc' is LLVM based, it is not yet fully supported by ruby and gems, please read `rvm requirements`.

GCCがXCodeのllvm-gccだとだめだそうで…

nissuk% gcc --version
i686-apple-darwin11-llvm-gcc-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Can’t install Ruby under Lion with RVM – GCC issues - Stack Overflow の回答を参考に--with-gcc=clangしたところ一応通りましたが clang: error: unsupported option '--with-libyaml' と言われていて全部は入っていないみたい…動くのかな?

nissuk% rvm install ruby-1.9.2-p320 --with-gcc=clang
Fetching yaml-0.1.4.tar.gz to /Users/nissuk/.rvm/archives
Extracting yaml-0.1.4.tar.gz to /Users/nissuk/.rvm/src
Configuring yaml in /Users/nissuk/.rvm/src/yaml-0.1.4.
Compiling yaml in /Users/nissuk/.rvm/src/yaml-0.1.4.
Installing yaml to /Users/nissuk/.rvm/usr
clang: error: unsupported option '--with-libyaml'
Building 'ruby-1.9.2-p320' using clang - but it's not (fully) supported, expect errors.
Installing Ruby from source to: /Users/nissuk/.rvm/rubies/ruby-1.9.2-p320, this may take a while depending on your cpu(s)...

ruby-1.9.2-p320 - #fetching 
ruby-1.9.2-p320 - #downloading ruby-1.9.2-p320, this may take a while depending on your connection...
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 8770k  100 8770k    0     0   718k      0  0:00:12  0:00:12 --:--:--  508k
ruby-1.9.2-p320 - #extracting ruby-1.9.2-p320 to /Users/nissuk/.rvm/src/ruby-1.9.2-p320
ruby-1.9.2-p320 - #extracted to /Users/nissuk/.rvm/src/ruby-1.9.2-p320
ruby-1.9.2-p320 - #configuring 
ruby-1.9.2-p320 - #compiling 
ruby-1.9.2-p320 - #installing 
Retrieving rubygems-1.8.24
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  371k  100  371k    0     0   551k      0 --:--:-- --:--:-- --:--:-- 1416k
Extracting rubygems-1.8.24 ...
Removing old Rubygems files...
Installing rubygems-1.8.24 for ruby-1.9.2-p320 ...
Installation of rubygems completed successfully.
ruby-1.9.2-p320 - adjusting #shebangs for (gem irb erb ri rdoc testrb rake).
ruby-1.9.2-p320 - #importing default gemsets (/Users/nissuk/.rvm/gemsets/)
Install of ruby-1.9.2-p320 - #complete 
clang: error: unsupported option '--with-libyaml'
Ruby 'ruby-1.9.2-p320' was build using clang - but it's not (fully) supported, expect errors.

2012-04-26

C#: Excelの読み込み(DataSet)

Visual Studio 2008のC# (C# 3.0 / .NET 3.5)でExcelを読み込むのにADO.NETの型付DataSetが使えればそれを使いたかったんですけどデータソースの設定ウィザードで設定を進めていくと 「Microsoft.VisualStudio.DataDesign.SyncDesigner.SyncFacade.SyncManager を読み込めませんでした」みたいに言われて先に進めないので普通のDataSetで読み込むことにしました。

Excelの一行目を列名として認識してくれる…

SyncManagerの件はVisual Studio 2008のService Pack(SP1)適用したら直りました。

2012-04-22

Google ChromeのアドレスバーとTLD

ドメインのTLDが「.local」だと「.com」等と同様にスキーム名(「http:」「http://」)をつけずに「example.local」のようにChromeのアドレスバーに入力してアドレスとして認識してくれることに気づいたので、最近はApacheでテスト環境を整備するときVirtualHostとhostsに設定するホスト名に「.local」を使っています(前「.localhost」を使っていましたがとても面倒でした…)。

テスト・例示用に使う他のTLDだとChromeにアドレスとして認識されるか気になったので試してみましたが何故か「.local」しか認識しないみたいでした。

表: Google Chrome(18.0.1025.162)のアドレスバーにドメインのみ入力してアドレスとして認識されるか (○: 認識される、×: 認識されない)
TLD 出典 結果
.local example.local -
.localhost example.localhost RFC 2606 ×
.test example.test RFC 2606 ×
.example example.example RFC 2606 ×
.invalid example.invalid RFC 2606 ×

「example.localhost/」のようにスラッシュをつけたらアドレスとして認識してくれました。これでもいいかも

2012-04-21

さくらのレンタルサーバ、ドメインキングのMySQLに外部から接続する

さくらのレンタルサーバの場合

さくらのレンタルサーバはSSHが使えるのでSSHポートフォワード経由でMySQLにアクセスできました。 ロリポップでもチカッパプランならSSHが使えるので同様のことができる気がします…(未検証です)。

1. SSHポートフォワードの設定

Tera Term(4.72)を使う場合は下記の手順で設定できます。

  1. メニューの 設定 > SSH転送 を選択
    image
  2. SSHポート転送画面で「追加」
    image
  3. ポート転送を行う向きの選択で「ローカルのポート」、ローカルで使うポート番号(例えば3306)、リモート側ホスト(例えばmysql00.sakura.ne.jp)、ポート(3306)を入力して「OK」
    image 

sshコマンド(Windowsならmsysgit等に入っています)を使う場合は下記で設定できます。

ssh -N -f -L ローカルで使うポート:DBホスト名:3306 サーバのユーザ名@サーバのホスト名

例えばDBホスト名が「mysql00.db.sakura.ne.jp」、ユーザ名が「user」の場合は下記です。

ssh -N -f -L 3306:mysql00.db.sakura.ne.jp:3306 user@user.sakura.ne.jp
2. 接続の確認

手っ取り早くMySQLクライアントで接続できるか試します。接続後クエリを投げてみて動くことを確認して下さい。

mysql -u サーバのユーザ名 -p

(ホストはlocalhostなので-h localhostをつけてもつけなくてもよいです。ローカルで使うポートを3306以外にした場合は「-P ポート番号」をつけます)

ドメインキングの場合

意外でしたがドメインキングは何もしなくても外部からアクセスできました。 サーバに設定したドメインが「example.com」、作成したユーザ名が「user」の場合、MySQLクライアントで下記のようにアクセスできます。

mysql -h example.com -u user -p

2012-04-17

キャメルケース補完

EclipseやVisual Studioなんかだと、キャメルケースで補完できますからね。
GetApplicationConfigurationString→SACS
SaveAllChangeSetToDatabase→SACSTD
見たいな感じで。
意外と知らない人もいるみたいですが、タイピングのリズムもいいし、好きな機能です。

長い関数名、変数名、どこまで許せる? | スラッシュドット・ジャパン デベロッパー

このコメント見るまで知らなかったので…Visual Studioでやってみました(手元にあったVisual C# 2010 Expressの例。Eclipseの例は Eclipseショートカットキーまとめ - watawata日記 にありました。Eclipseのショートカットについてとても参考になります。あとこの記事を真似してBB FlashBackを使ってみました)。

長い名前といえばDOM、ということで 連載! とことん C#: 第 22 回 LINQ to XML で楽々 XML 文書処理 のDOMのサンプルコードを入力しています。


Visual Studio 2008だとできないみたい…?

2012-04-15

Apache: RewriteBaseは書き換え後のパスのベース

mod_rewriteでURLの書き換えルールを書く機会は頻繁にあるわけではないので、いざルールを書くとなるといろいろ忘れていて結構時間を取られます…。今日はmod_rewriteのRewriteBaseとその周辺についてまとめておきたいと思います。

例えば

  1. サーバのドキュメントルートが /var/www/vhosts/example.local/
  2. サーバのURLが http://example.local/
  3. http://example.local/abc/def.html に来たアクセスを http://example.local/abc/ghi.html に書き換えたい
  4. そのためドキュメントルートの.htaccess(/var/www/vhosts/example.local/.htaccess)に書き換えルールを書く

とき、RewriteBase /abcとか/abc/にしてやれば下記のように書けるかな…と考えて

RewriteEngine On
RewriteBase /abc
RewriteRule ^def\.html$ ghi.html [L]

と書いても書き換えはできません。RewriteBaseは書き換え後のパス指定(例だとghi.html)が相対パスだった時にそこに使われる(例だと/abc/ghi.html)だけで、マッチパターン(例だと^def\.html$)には全く関係しないので下記のように書く必要があります。

RewriteEngine On
RewriteBase /abc
RewriteRule ^abc/def\.html$ ghi.html [L]

ところで下記は×です。

RewriteEngine On
RewriteBase /abc
RewriteRule ^/abc/def\.html$ ghi.html [L]

ネット上を調べると上記例のようにRewriteRuleのマッチパターンをスラッシュ(/)から始めている記述がありますが、RewriteRuleに渡ってくるパスがスラッシュから始まるのはhttpd.confにRewriteRuleを書いた時だけで、.htaccessに書いた時は.htaccessが置いてあるディレクトリからの相対パス(上記例だと abc/def.html。RewriteLogで「strip per-dir prefix」と書かれている箇所)がRewriteRuleに渡ってくるため最初のスラッシュがマッチしなくなります。

RewriteBaseを使わない場合

RewriteBaseを使わない場合は下記のように書けます。

RewriteEngine On
RewriteRule ^abc/def\.html$ /abc/ghi.html [L]

書き換え後のパス(例だと/abc/ghi.html)が相対パスではなくURLの絶対パスなのでRewriteBaseを気にする必要がありません。

ところでRewriteBaseを指定しなかった場合の既定値は.htaccessを置いたディレクトリの物理パスです。そしてRewriteBaseは書き換え後の相対パスのベースです。つまり上記例に加えて下記の3つはすべて結果的に同じです。

RewriteEngine On
RewriteRule ^abc/def\.html$ abc/ghi.html [L]
RewriteEngine On
RewriteBase /var/www/vhosts/example.local/abc
RewriteRule ^abc/def\.html$ ghi.html [L]
RewriteEngine On
RewriteRule ^abc/def\.html$ /var/www/vhosts/example.local/abc/ghi.html [L]

なぜURLでも物理パスでもいいのかはRewriteLogを見るとわかりますが、書き換え後のパスが物理パスだった場合RewriteRuleでパターンマッチして内部リダイレクトさせる前に「strip document_root prefix」という形でドキュメントルートの物理パスを取り除いているためです。

ただし外部リダイレクト(RewriteRuleにRフラグをつける)にすると話は変わってきて、例えば下記のようにすると

RewriteEngine On
RewriteRule ^abc/def\.html$ /var/www/vhosts/example.local/abc/ghi.html [R,L]

ドキュメントルートの物理パスを取り除かずに外部リダイレクトするので結果としてhttp://example.local/var/www/vhosts/example.local/abc/ghi.html にアクセスしてしまいます。

まとめ

まとめとしてはタイトルの通りですが、mod_rewriteはややこしいです。RewriteBase以外でもしょっちゅうはまります。RewriteLogを見れば内部でどうやって書き換えが行われているのかが記録されるので、mod_rewriteが意図しない動作をするときはRewriteLogを見ましょう(RewriteLogについてはできれば後日まとめたいと思いますが、RewriteLogLevel - Httpd Wiki にあるようなログが確認できます)。

2012-04-12

Java: Exifから位置情報を取得する(Sanselan)

Apache CommonsのSanselanを使うと写真の位置情報(緯度と経度)が簡単に取得できます。下記の例では写真("test.jpg”)の位置情報を単純に取得して出力します。

上記と「2地点の緯度と経度からおおよその距離を計算する」を組み合わせると写真の位置情報から写真を自動的に場所ごとのフォルダに振り分けたりすることができます。

2地点の緯度と経度からおおよその距離を計算する

球面三角法(PDF) の最後の「3-2. 地上の2地点間の距離」がわかりやすかったので少し引用します。

image

図の太線で囲まれた球面三角形に余弦法則を適用すると

であり、

によって x を計算できる。この場合は0≦ x ≦ 180°なので、cos-1によって得た結果にあいまいさは無い。2地点間の距離 L は、

によって計算できる。ただし x はラジアンの値にしておくことが必要である。

プログラム(Java)で書くと下のような感じです。度はラジアンにします(* Math.PI / 180で変換していますがJavaならMath.toRadians()でもいいです。PHPならdeg2rad())。

 

カシオの計算サイトに同様の計算式で距離を計算するフォームがあって便利でした。

2012-04-10

PgcEdit: 自動ループ再生DVD

DVD Shrinkで複数VOBを1つにまとめたDVDのループ再生(リピート)が上手くいかなかったのでPgcEditを使ってループさせるようにしました。

  1. http://download.videohelp.com/r0lz/pgcedit/ からPgcEditとShrinkプラグインをダウンロードして解凍
  2. PgcEditを一旦起動してpluginsフォルダを生成してもらう
  3. Shrinkプラグイン(dvdshrink_plugin.tcl)をpluginsフォルダに放り込む
  4. PgcEditを起動し直してDVDデータのあるフォルダを開く
  5. plugins > DVDShrink > Enhance and fix authoringを選択
    image
  6. 「loop back to the beginning of the first title.」にチェックしてOKimage
  7. 保存

確認のためDVDデータをISOに変換、Daemon ToolsでマウントしてWindows Media Playerで再生してみたところ「この DVD は、ユーザーの国/地域での再生が禁止されているため、再生できません。地域にあったディスクを入力して下さい。」と言われてしまいました(リージョンのエラー?Daemon ToolsのデバイスパラメータのDVD地域は問題ないです)。PgcEditのせいかと思いましたが手元の環境ではShrinkでVOB編集して作成したISOの場合Deamon ToolsでマウントするとPgcEdit関係なく同じエラーが出ていました…。

Windows Media PlayerでIFOを再生してみるか再生プレイヤーをVLC Media Playerにして確認するか実際にDVDに書き込むかすれば確認できるみたいです。

2012-04-08

Antタスクのデバッグ (S2JDBC-Gen)

S2JDBC-Genのgen-entity等が出力するコードを変更するのに内部動作を調べていたんですがAntでそのままgen-entityタスクを実行するとEclipseでブレークポイントを付けても止まらないので Ant カスタムタスクのデバッグ方法:アーキテクト360を参考に下記のようなコードを書いて実行しています(Antのant.jarとant-launcher.jarが必要です)。

public class AntDebug {
public static void main(String[] args) {
org.apache.tools.ant.Main.main(
"-f s2jdbc-gen-build.xml gen-entity".split(" "));
}
}

これでS2JDBC-Gen(s2jdbc-gen-2.4.43.jar)内のclassファイルにブレークポイントを付けて止めることはできましたが、そのままだとソースを書き換えてテストすることができないので Seasar2 – Downloads からS2JDBC-Genのソース群をダウンロードしてsrc/main/java以下にjarと同じ構成で配置します。これでjarを弄らなくてもソースの方を変更すれば変更が反映されます(エラーになるファイルが若干ありましたが今回調べたかった箇所はエラーになるファイルが不要だったため単純に削除するだけで大丈夫でした) 。

また GenerateServiceCommand#doExecute() 等の中にブレークポイントを付けてもそれを呼び出している AbstractTask#executeCommand() がコマンドをJavaタスク内で実行しているせいかブレークポイントで止まらないので取り急ぎToStringBuilderを使って変数の内容を出力して確認しています…。

それとgen-entityした後の生成ファイル群を削除するのがすごく面倒だなぁ…と思いgen-entityする直前の状態をgit commit → gen-entity後にgit clean -dfで生成されたファイルをすべて削除、とすることで対処しています。便利ですがその後にEclipseのメニューで プロジェクト > クリーン しておかないと実行した時に「log4j:WARN No appenders could be found for logger」等と言われてエラーになるので注意です。

2012-04-05

Eclipse: テンプレートで使用するパッケージを自動でimportさせる

(Eclipse 3.7 Indigo Pleiades All In One)

普通にテンプレートを書いて挿入するとパッケージのimportがされていなくてエラーになることがありますが、テンプレート変数のimportでimportの設定ができるそうです。

${:import([type[,type]*])}
すでにインポートされていない各タイプのインポート・ステートメントを追加します。競合するイン
ポートが存在する場合、何も実行しません。何にも評価されません。

例:
${:import(java.util.List, java.util.Collection)}

commons-langのToStringBuilderとlog4jでPHPのvar_dump()のようにオブジェクトのダンプをするコードのテンプレートを作成する場合は下記のように記述すればOKでした。

${:import(org.apache.log4j.Logger, org.apache.commons.lang3.builder.ToStringBuilder, org.apache.commons.lang3.builder.ToStringStyle)}Logger.getLogger(getClass()).debug(ToStringBuilder.reflectionToString(${cursor}, ToStringStyle.MULTI_LINE_STYLE));

Eclipseテンプレート

${:import}の行末で改行するとインデントの調整がずれる(以降の行もimportのインデントレベルと同じインデントレベルになる)ので${:import}の行末では改行しないほうがいいみたいです。