Windowsで使えるUnix(tcsh)ライクなシェルの紹介

とある事情(Windowsしか対応してないプリンタサーバのせい)のため、
LinuxからWindowsに作業環境を変えて開発にいそしんでおります。
Linuxシステム開発したせいか、Windowsでの開発もコンソールメインの生活になりつつあります。


ただ、Windowsでのコンソール生活は非常に窮屈でして、
テキスト編集はgvimのコンソール版をありがたく使わせていただいていますが、
grepとかlvとかがないので我慢の日々です。
# GNU Tools for Win32 的なものは文字化けるし(昔の経験)

ただ、どうしても機能が非常にpoorなコマンドプロンプトに嫌気がしてしょうがない。
tcshWindows移植版もつかってみたのですがコマンドプロンプトを使うbatファイルとかの出力が別ウィンドウになって結果が見れないのです・・・。
railsだと、rake db:migrate とか。とくべつな設定があるのでしょうか? 
あと、Cygwinは、windows側のrubyやrubygemが変な動作するので放置。
まぁ、ちゃんと設定すればいいんでしょうけど・・・。


ま、そんなこんなで、世界のどこかにUnixライクなコマンドプロンプトを作ってる人がいるに違いないという希望的観測の元、グーグル先生と相談してみたところ、やはりでてくるものです。
# なければ自分でつくってしまえという無謀な計画もあったわけですが。

Nihongo Yet Another OSes Shell
http://www.nyaos.org/index.cgi?p=FrontPage.ja

tcshライクなシェルです。
日本の方が作られてるようで日本語もばっちり。
コマンド補完もあるし、c-a, c-eもつかえるし、c-p, c-nとか、c-k, c-yもできちゃう。
ってなんのこっちゃですかね?(要はmacsライクなカーソルの移動方法です)
あと、エイリアス機能もあるし、便利にするための独自の機能も多々あります。


個人的には機能や動作的な面では問題ないので、しばらく開発に使ってみようと思います。
まぁ、贅沢を言えば、コマンドプロンプトの枠の中で動いているのでウィンドウサイズの横幅固定になってしまっているのをどうにかしてほしいわけですが。。。

ちなみに最終更新が2004年です・・・開発とまってるのでしょうか。
いまのところ、バグに遭遇してないのである程度完成されちゃってるのかと思いますが。


# MOONGIFT的な紹介文を書くセンスはありませんでした。

JRubyOnRailsに再挑戦

以前、JRubyOnRails に挑戦したもののうまく動作せずに放置しましたが、
JRuby1.1.4がリリースされたので再挑戦してみました。


今回の環境は、Windows XP + jruby 1.1.4 + Rails 2.1.0 + Glassfish です。
jrubyではsqlite3-rubyがサポートされてないくさいので、jdbc版を使いました。


以下、インストール&実行手順。

JDK

jdk5(SE)以降をインストールし、インストールディレクトリをJAVA_HOMEと設定。
%JAVA_HOME%\binをPATHに通す

JRuby

http://dist.codehaus.org/jruby/jruby-bin-1.1.4.zip

をダウンロードし、c:\jruby1.1.4あたりに解凍。
c:\jruby1.1.4\binを、PATHに通す。

Rubygemsでインストール

もとからRubygemsは入っています。
なので、早速、Railsなどをインストールします。

 jruby -S gem  install rails


DB関係はここをみてインストール(適当ですが・・・)

http://wiki.jruby.org/wiki/Running_Rails_with_ActiveRecord-JDBC

 jruby -S gem install activerecord-jdbsqlite3-adapter
 jruby -S gem install jdbc-sqlite3


Glassfish のインストール

 jruby -S gem install glassfish

Rails側の変更点

先ほどのJDBC関連のURLの中にあるように、


config/database.yamlに,

evelopment:
adapter: jdbcsqlite3
url: jdbc:sqlite:test.db


config/initializers/jruby.rbに、

if RUBY_PLATFORM =~ /java/
require 'rubygems'
gem 'activerecord-jdbcsqlite3-adapter'
require 'jdbc_adapter'
end

を記述。

Rails起動 (With Glassfish)

RAILS_ROOTにて、

 jruby -S glassfish_rails .

で起動します。


体感速度ですが、Mongrelよりはやいんじゃないかとおもったり。


しかし、とりあえず動作するもののなんか変です。

HTTP/1.1 200 OK Content-Type: text/html; charset=iso-8859-1 Transfer-Encoding: chunked Date: Mon, 01 Sep 2008 05:47:46 GMT

たまにこんなのがHTMLの最後に引っ付いてしまいます。
WEBrickの方では問題なさそうですが・・・。


追記:
F5を連打すると、GlassfishでもWEBrickでも、たまにIOエラーが発生してCSSがロードされないことが・・・・。

Rubyでwhereコマンドを書いてみた (Windows)

実際書いたのはちょっと前ですが、Windowsにwhere(which)コマンドがないのでRubyのコーディング練習がてら自分で書いてみました。


whereっぽい実装ですが、厳密にはPATH中の実行ファイルを探してすべて表示するだけのプログラムです。
# whereとwhichの動作って違うんですね。


さっそくコードです。
スパゲッティコードなので、エラーとか例外とかの処理は省略してます。

find_target = ARGV.shift
paths = ENV["PATH"].split(";")
pathexts = [""] + ENV["PATHEXT"].split(";").map{|ext| ext.downcase}
found = paths.map {|path|
    pathexts.map {|ext|
        "#{path}\\#{find_target}#{ext}"
    }.delete_if {|target|
        not File.exist?(target)
    }
}.flatten!

if found.empty?
    puts "not found"
else
    puts found.join("\n")
end


コードを書いてて、検索部分が1行でかけてしまうRubyの素敵さに気づきました。
多少強引なところもありますけど。(flatten!とか)
やろうと思えばpathsとかpathextsとかも1行の中に入れれますね。
まぁ、可読性落として、そこまでする必要はないと思いますが・・・。


最初は、delete_ifの部分は、if文を使ってファイルがあればfoundに追加・・・ってしてました。
でも、先に調べるファイルの候補作ってるので、delete_ifで存在しない奴を消してしまったほうがスマートだろうと思い現在のコードに。
Cだと分岐がない方が高速になる可能性ありますけど、Rubyの場合無意味な気も・・・。


あと、Windowsに依存してるところの説明を。


まず、環境変数のPATHEXT。
ここにコマンドを実行する際に省略可能な拡張子が入っています。
これがあるから、example.exe を example とタイプするだけで実行できるみたいです。
このプログラムでは、一応拡張子がないものも検索するようにしてます。
実行はできないんですが。
pathexts に空の文字列を追加してるのを消せば本来の動作になるかと。


それと、cdとかdirについて。
コマンドプロンプトのビルトインコマンドです。
これは検索しても見つからないので、独自に対応するしかないかと。
tcshでも、

cd is a shell built-in

って出ます。


これを exerb でexeにしてやって立派な(?)where.exeとして働いてくれてます。

リレーションを持ったARオブジェクトをセッションにいれる場合の問題(Rails2.x ?)

リレーションを持ったARのオブジェクトをセッションに入れる場合の問題についてです。

たとえば、

 Item -> Category
                                • -
items name:string category:references categories name:string

のようなDBがあったとして、itemに belongs_to :category と定義しておく。

itemの作成ページ(newアクション)とcreateアクションの間に確認画面を挟むために、セッションを使い次のようなコードを書いた場合、@itemのCategoryのオブジェクト(@item.category)が変更できなくなってしまいました。

# items_controller.rb
def new
  session[:item] = @item = session[:item] || Item.new
end
def confirm
  @item = session[:item]
  @item.attributes = params[:item]
end
def create
  @item = session[:item]
  @item.save!
  redirect_to @item
end

確認画面にitemのcategoryを表示する場合、最初の表示では変更が反映されるが、2度目以降は反映されなくなります。
@item.category_idを直接変更しても、@item.categoryは変更されませんでした。
@item.category.idとすると最初に選らんだcategoryのidになります。

想像ですが、どうやら sessionに入れることで、キャッシュのコントロールがおかしくなってしまうのではないかと思います。

対策としては、

@item.attributes = params[:item]
@item.category.reload

というように、@item.category_idを更新した後に、@item.categoryをreloadしてやることで値が読みなおされ正常に動作するようになりました。

1.2.x系ではならなかった(と思う)ので、ついハマってしましました・・・・


というか、確認画面ってどういう風に実装するのがいいんでしょうね。
セッションを使うとセッションを削除するタイミングが難しいし、かといってflashじゃ想定外のページ遷移で消えちゃうし、hidden渡しはコードが面倒になるし。


まぁ、どこかの記事で海外では確認画面なんてナンセンスだと思われているというのをみた気もしますが・・・
入力した内容を確認しない人は、確認画面があっても、結局確認とかしないという感じの理由。
海外のフリーソフトで確認画面がないのもがあるのもそのためだと言われれば納得できるような。

Rails 2.1.0 TimeZone機能(TimeWithZoneクラス)は Marshal に非対応・・・

gem でupdate したら、Rails 2.1.0 になったついでに、開発も 2.1 に移行してみました。
2.1からは、Timezoneをサポートしたということです。
http://mad.ly/2008/04/09/rails-21-time-zone-support-an-overview/


ちょっと期待してたんですが致命的な問題があるようです。

時間をdatetime_selectで入力して、モデルに格納し、それをセッション変数に保存して、次のページに渡すということをしていました。


そしたら、ずれるんです。 時間が。 9時間ほど。


動作を見ていくと、セッションに時間(TimeWithZoneのオブジェクト)を入れると時間がずれます。
どうやらマーシャルすると、「マーシャル前の時間+ローカルのタイムゾーンオフセット」した時間になるようです。



どうみてもバグです。 ほんt(ry


ぐぐってみると、この問題に気づいた方が検証され、自力で修正案を出されていました。http://rails.lighthouseapp.com/projects/8994/tickets/558-timewithzone-fails-to-unmarshal-properly


個人的には、この機能を殺すことで解決することにしました。

# config/environment.rb
# config.time_zone = 'UTC'

config.time_zone をコメントアウトしてやれば、この機能は停止するようです。

Fedora9に Sun Java SE 1.6.0 update 7 をインストール

ノートを修理に出して、OSが初期化されたので、Fedora9を再インストールしました。


で、Javaを再インストールするときに、ハマったのでメモ。


普通、Redhat系でSunJavaをインストールするには、

http://wiki.alfresco.com/wiki/Installing_Alfresco_Community_2.9B_on_Centos_5.1#Install_JDK_1.6.06

のような手順でインストールします。

java-1.6.0-sun-compat-1.6.0  はここからダウンロード
ftp://jpackage.hmdc.harvard.edu/JPackage/1.7/generic/RPMS.non-free/

が、現在の、JDKは 6.0 update 7 で、これに対応する java-1.6.0-sun-compat-1.6.0 がありません。
リンク先のインストール方法では、update6をダウンロードして回避してますが、
ここはあえてjava-1.6.0-sun-compat-1.6.0のソースRPMを拝借して、書き換えてみることに。
# だって、もう update7 いれちゃったし ;;

というわけで、改造メモ

ソースRPMをインストール

rpm -ivh java-1.6.0-sun-compat-1.6.0.06-1jpp.src.rpm

インストールしたソースは、つぎのディレクトリ以下に入るようで。

/usr/src/redhat/

SPECファイルを書き換え

$ cd /usr/src/redhat/SPECS/
$ sudo vi java-1.6.0-sun-compat.spec

次のように書き換えます。
4行目:

%define buildver        07

622行目:

 --slave %{_bindir}/javaws                 javaws                      %{_jvmdir}/%{jrelnk}/javaws

622行目の %{_datadir}/javaws を %{_bindir}/javaws に変更しないといけないのは、バグだと思うんですが。
RPMだとインストールはちゃんとできたと思うので、SRPMだけ直されてないのかな?

RPMをビルド

$ sudo rpmbuild -bb java-1.6.0-sun-compat.spec

/usr/src/redhat/RPMS/i586/java-1.6.0-sun-compat-1.6.0.07-1jpp.i586.rpm
ができます

RPMをインストール

$ cd /usr/src/redhat/RPMS/i586/java-1.6.0-sun-compat-1.6.0.07-1jpp.i586.rpm


あとは、通常どおり、

$ sudo /usr/sbin/alternatives --config java

を実行して、sun-javaに切り替えるだけです。

以上で、とりあえず java コマンドは置き換わりました。
なにも考えずに書き換えただけですので、ほんとに動くかは保証はありません・・・。
早く本家で更新がリリースされることを祈ります。

Xft対応のEmacs23をリポジトリからインストール

Fedora9に入れ替えてから、emacsを使う機会がなかったのですがようやくemacsの出番がきまして、
いざ使おうとなるとやはりフォントが見にくくてXft対応のemacsをインストールすることにしました。


Fedora8の時は、たしか、

http://blog.goo.ne.jp/cilsetyu/e/59a833c363459a6130fa3861493a8240

を参考にして、自分でビルドしたのですが、


本家?のXftGnuEmacsのサイト、

http://www.emacswiki.org/cgi-bin/wiki/XftGnuEmacs#toc8

に、Fedora8/9について記述があり、

# rpm -ivh http://people.redhat.com/coldwell/emacs/repo/fedora/emacs-release-23-1.fc8.noarch.rpm
# yum update 'emacs*'

だけでインストール完了。すごい幸せ。


fedora公式で入るemacs22から、emacs-23に置き換わり違和感なしで使えます。
あとは、 .emacs に、

(add-to-list 'default-frame-alist '(font . "フォント名-フォントサイズ"))

を追加すればいいようです。
他に設定はしてないのですが、フォントが見違えるほど綺麗に表示されてます。
細かいことは理解してないので、

http://www.emacswiki.org/cgi-bin/wiki/XftGnuEmacs#toc14

をみてください。


ちなみに、普通にemacsを起動しましたが、もとから入っていたemacsのel関連はとりあえずエラーを吐いてないので大丈夫なのかなと。
個別にロードするのに関しては未検証です。