素敵ツール

screenを使って何をしたかったかと云えば、ターミナルを複数開くのが嫌だったからで、タブで管理できるのがいいなと思ったのが始まり。
screenの設定が微妙に完成しないのが歯がゆかったですが、普通にタブ使えるコンソールツールってあるんですね。

で、Poderosaをダウンロードして使ってみた。
イイ!これはイイですよ。
タブ機能はもちろん、ウィンドウ分割やCygwinコンソール呼び出しまで出来る。

もっと早く調べればヨカタヨ。
これでTeraTermから脱却ができます。

続screen

2006/01/19 の記事の続き。

前回は、

[1]cygwin(ローカル:sjis) -> [2]screen(ローカル:sjis) -> [3]ssh(リモート:utf8)

  • [1]でviでsjisのファイル編集は可能
  • [2]でviでsjisファイルが文字化け
  • [3]でviで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)

  • [1]でviでsjisのファイル編集は可能
  • [2]でviでsjisファイルが文字化けなし!
  • [3]でviで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)

  • [1]でviでsjisのファイル編集は可能
  • [2]でviでsjisファイルが文字化け
  • [3]でviで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に値を動的に設定するにはどうするんだろう?

 さてと

1年ぐらい前まではJavaの開発なんかもしてましたが、最近はめっきりJavaに触れる機会も減り、どんどん世間の流行からおいてかれてる気がする今日この頃。

そんな訳で重い腰をあげて勉強を始めようかというのがこのBlogのスタンスです。時間の合間に勉強したことをメモしていく備忘録。いつまで続きますか・・・