続screen
2006/01/19 の記事の続き。
前回は、
[1]cygwin(ローカル:sjis) -> [2]screen(ローカル:sjis) -> [3]ssh(リモート:utf8)
と云ったところで行き詰っていました。
色々調べて、.screenrcの記述を以下のように見直し。
bind U eval "encoding utf8" "stuff 'export LANG=ja_JP.UTF-8\012'" bind E eval "encoding euc" "stuff 'export LANG=ja_JP.EUC-JP\012'" bind J eval "encoding sjis" "stuff 'export LANG=ja_JP.SJIS\012'" escape ^z^z encoding SJIS defencoding SJIS termcapinfo cygwin KJ=SJIS vbell off defhstatus I^En:^EtI shell -$SHELL startup_message off autodetach on hardstatus ignore "%w | %h" hardstatus alwayslastline "[%02c] %`%-w%{=b mw}%n %t%{-}%+w" defscrollback 3000
termcapinfo cygwin KJ=SJISと云う行を追加しました。そうすると、
[1]cygwin(ローカル:sjis) -> [2]screen(ローカル:sjis) -> [3]ssh(リモート:utf8)
一歩前進。
さらに[3]でC-Z Uを実行して、エンコードをUTF8に変更してみたところ、viで開いたUTF8のファイルが文字化けせずに読めるように。
やった!!!と思ったのも束の間、A-Z等のキーは正しく入力できるのですが、それ以外のキーが見事に文字化け。おかげでviから抜ける事もできなくなりました。
あとちょっと。あとちょっとなんです。ぐむー。
拡張モジュール
を作ってみた。
PHPから拡張モジュール経由で「Hello World!」と出力したかっただけなのに、結構てこずってしまった。忘れないようにメモ。
# cd {PHPのソースファイル}/ext/
# ./ext_skel --extname="hello"
# cd hello
# vi hello.c
zend_function_entry hello_functions[] = { PHP_FE(confirm_hello_compiled, NULL) PHP_FE(say_hello, NULL) /* 追加 */ {NULL, NULL, NULL} }; /* Say Hello モジュール */ PHP_FUNCTION(say_hello) { char *arg = NULL; int arg_len, len; char string[256]; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) { return; } len = sprintf(string, "Hello World!! Mr.%78s", arg); RETURN_STRINGL(string, len, 1); }
# vi php_hello.h
PHP_FUNCTION(confirm_hello_compiled); /* For testing, remove later. */ PHP_FUNCTION(say_hello); /* 追加*/
# vi .config.m4
PHP_ARG_ENABLE(hello, whether to enable hello support, Make sure that the comment is aligned: [ --enable-hello Enable hello support]) SEARCH_FOR="/include/hello.h" # you most likely want to change this LIBNAME=hello # you may want to change this LIBSYMBOL=hello_do # you most likely want to change this
# phpize
# ./configure
# make
# make install
# cd {PHP_HOME}/extensions
# ln -s extensions/no-debug-non-zts-20020429*1/hello.so hello.so
ここまで出来たらあとはサンプルのPHPを作るだけ。
書いたコードはこんな感じ。
<?php dl('hello.so'); print say_hello('hogehoge'); ?>
ブラウザにアクセスしてみる。
Hello World!! Mr. hogehoge
無事に出力されました。
hello.cやphp_hello.hの修正はなんとなく理解できるんだけど、config.m4の修正内容がいまいち理解できず。最後のは、soの名前を決めてるんだと思うけど、最初の三行はなんだろう・・・。消すと、make installに失敗するんだよなぁ。もう少し調べてみよう。
*1:環境によって名前は微妙に違うかも
新発見
id:naoyaさんの2005/12/23の記事「GNU screen いろいろまとめ。」を見て、おおこれは面白そうだなと。んで急遽ローカル環境にcygwin+screen+zshをインスコ。
なんだかよく分からないエラーにぶち当たりcygwin再インストールの憂き目に会いつつもどうにかこうにかセットアップ完了。
.screenrcに設定してみた内容はこんな感じ。
bind 'U' eval "encoding utf8" "stuff 'export LANG=ja_JP.UTF-8\012'" bind 'E' eval "encoding euc" "stuff 'export LANG=ja_JP.EUC-JP\012'" bind 'J' eval "encoding sjis" "stuff 'export LANG=ja_JP.SJIS\012'" escape ^z^z defencoding sjis #defutf8 on vbell off defhstatus I^En:^EtI shell -$SHELL startup_message off autodetach on hardstatus ignore "%w | %h" hardstatus alwayslastline "[%02c] %`%-w%{=b mw}%n %t%{-}%+w" defscrollback 3000
screenをいくつも立ち上げ、windowに名前をつけ、各々がsshで別サーバに接続。window分割しながら、tabでバッファを移動する。シビレます。
ただ、いくつか問題が。
cygwinインストールしたローカル環境(Win)の文字コードはsjisで、sshでつなぐ先のサーバの文字コードがUTF-8だったりした時に、viで編集しようとすると激しく文字化けします。ちょっと厄介。
流れはこんな感じなのですが、
[1]cygwin(ローカル:sjis) -> [2]screen(ローカル:sjis) -> [3]ssh(リモート:utf8)
といった具合になっています。
ちなみにローカルの.vimrcの中身は
set encoding=japan set fileencodings=iso-2002-jp,utf-8,euc-jp,cp932 set number highlight WastedSpace ctermbg=6 match WastedSpace /\t\|\s\+$\|!!/
こんな感じ。
今は、.screenrcのdefencodingをsjisにしているので、[3]で文字化けするのは仕方ないかな*1と思うのですが、[2]で化けるのは何故なんだろう?
*1:リモートの.vimrcも修正する必要あるよなぁ
Spring Framework 始めました2
Beanに値を動的に設定するにはどうするんだろう?なんて漠然と考えていた訳ですが、普通にsetterメソッドを呼び出せばいいんですね。定義ファイル(beans.xml)に記述しなおしたりする必要があるのかと思っちゃいました。初期値が必要なもの意外は普通はnullを設定するものなのでしょうかね?
さて、このBeanですがBean要素には,singleton属性というものがあります。
singleton属性の値は(true/false)で、trueの場合BeanのインスタンスはBeanFactory内で共有され同一インスタンスが返却されます。falseの場合BeanFactoryから返されるインスタンスは常に新しいものとなるそうです。
早速検証してみます。
前回作ったbeans.xmlを以下のように修正します。
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean name="m_message" class="sp.sample.data.Message" singleton="true"> <property name="text"><value>Good Morning !!</value></property> </bean> <bean name="e_message" class="sp.sample.data.Message" singleton="false"> <property name="text"><value>Good Evening !!</value></property> </bean> </beans>
次にメッセージ表示部分(Person.java)を以下のように変更。
package sp.sample.core; import java.util.ArrayList; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.FileSystemResource; import sp.sample.data.Message; public class Person { public static void main (String[] args) { try { XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml")); Message mMessage = (Message)factory.getBean("m_message"); Message eMessage = (Message)factory.getBean("e_message"); ArrayList<Message> messages = new ArrayList<Message>(); messages.add(mMessage); messages.add(eMessage); // メッセージの出力 showMessage(messages); // 再設定 mMessage.setText("Bad Morning !!"); eMessage.setText("Bad Evening !!"); // 再取得 mMessage = (Message)factory.getBean("m_message"); eMessage = (Message)factory.getBean("e_message"); messages.clear(); messages.add(mMessage); messages.add(eMessage); // メッセージの再出力 showMessage(messages); } catch (Exception e) { e.printStackTrace(); } } /** * メッセージを出力します。 * @param list メッセージのリスト */ private static void showMessage(ArrayList<Message> list) { for (Message m : list) { System.out.printf("message=%s\n", m.getText()); } } }
さあ、実行してみましょう。
message=Good Morning !! message=Good Evening !! message=Bad Morning !! message=Good Evening !!
singlton属性を設定したbean:m_messageの方はbeanが共有化*1されている為、変更が反映されている事がわかります。一方のbean:e_messageは常に新しいインスタンスが返却される為、変更よりも定義ファイルの値が有効になっています。
*1:永続化?
Spring Framework 始めました
私がゴリゴリJavaをコーディングしていた頃はEJB全盛期だった訳ですが、ふと周りを見渡してみるとDIなんて言葉が闊歩している。遅れているな自分・・・
と云う事で早速私も遅まきながらDIの世界を体験してみようと思います。
DI(Dependency Injection)で検索すると良く目にするのがSpring FrameworkというDIコンテナ。
これがわりと有名っぽいので、まあ何はともあれ早速コーディング開始です。
まずはBeanを作る。こんな感じ。
#Message.java
package sp.sample.data; public class Message { public String text; public String getText() { return text; } public void setText(String text) { this.text = text; } }
Beanが出来たので、次はBean用定義ファイルを作る。
#beans.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean name="m_message" class="sp.sample.data.Message"> <property name="text"><value>Good Morning !!</value></property> </bean> <bean name="e_message" class="sp.sample.data.Message"> <property name="text"><value>Good Evening !!</value></property> </bean> </beans>
最後に呼び出す人を作る。
#Person.java
package sp.sample.core; import org.springframework.beans.factory.xml.XmlBeanFactory; import org.springframework.core.io.FileSystemResource; import sp.sample.data.Message; public class Person { public static void main (String[] args) { try { XmlBeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml")); Message mMessage = (Message)factory.getBean("m_message"); Message eMessage = (Message)factory.getBean("e_message"); System.out.printf("mMessage=%s\n", mMessage.getText()); System.out.printf("eMessage=%s\n", eMessage.getText()); } catch (Exception e) { e.printStackTrace(); } } }
んで、クラスパスにspring.jarを追加して実行!!
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/logging/LogFactory at org.springframework.beans.factory.support.AbstractBeanFactory.<init>(AbstractBeanFactory.java:99) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.<init>(AbstractAutowireCapableBeanFactory.java:104) at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.<init>(AbstractAutowireCapableBeanFactory.java:113) at org.springframework.beans.factory.support.DefaultListableBeanFactory.<init>(DefaultListableBeanFactory.java:87) at org.springframework.beans.factory.xml.XmlBeanFactory.<init>(XmlBeanFactory.java:67) at org.springframework.beans.factory.xml.XmlBeanFactory.<init>(XmlBeanFactory.java:56) at sp.sample.core.Person.main(Person.java:11)
ありゃ。エラーが。apache.commons.loggingも必要なのね。
と云う事でクラスパスにcommons-logging.jarを追加して再度実行!!
mMessage=Good Morning !! eMessage=Good Evening !!
はい。無事に出力されました。簡単ですね。
[memo]
- 定義ファイルが冗長になってきた時の管理は?
- Beanに値を動的に設定するにはどうするんだろう?