ChaichanPapa-World !

燈明日記(2008/02

◆ インデックス

◆ 2008年2月

2008-02-29 つづき、えらいこった

いや、明日、代役で英語圏(物理的な場所は都内某所)へ、リスニングもテキストもすべて英語とのこと・・・。

http://d.hatena.ne.jp/chaichanPaPa/20080228/1204203636

同時通訳がありましたので、助かりました。

しかし、ネイティブの英語の発音の聞き取りにも挑戦したかったし・・・両方、聞いていたのですが、結局、「二兎追う者は一兎も得ず」状態で終わってしまいました。悲しかったです。

2008-02-29 Word 2007 および Word 2003 で印刷に問題がある場合のトラブルシューティング方法

リンクメモ:「Word 2007 および Word 2003 で印刷に問題がある場合のトラブルシューティング方法」

2008-02-29 Microsoft 圧縮 (LZH 形式) フォルダの使い方

LZH形式解凍機能は、少なくともMicrosoft Windows XPなら、アドオン(フリー)でMSから提供されている。


リンクメモ:「Microsoft 圧縮 (LZH 形式) フォルダの使い方」

2008-02-29 タスクスケジューラからの多重起動について

結論から言うと多重起動はされません。

タスクスケジューラは、多重起動しないような仕様になっている?


と言うことで、プロセス地獄には、ならないようです。

2008-02-28 えらいこった

いや、明日、代役で英語圏(物理的な場所は都内某所)へ、リスニングもテキストもすべて英語とのこと・・・。

いまから、予習します。ですので、今日はここまで、英語ショックがなければ、またあした!

2008-02-27 有難嬉悲しメモ(2008/02/27)

2008-02-27 Perlでシングルトンパターン! (デザインパターン)

Perlでデザインパターン 第5弾(シングルトンパターン)

シングルトンパターンとは、指定したクラスのインスタンスが絶対に一つしか存在しないことを保証するパターンです。


一般的なシングルトンパターンのクラス図
     +---------------------+
     |     Singleton       |
     +---------------------+
     | -$singleton         |
     +---------------------+
     |                     |
     | +getInstance        |
     |                     |
     +---------------------+

サンプル1
Singleton.pm
package Singleton;
use strict;

my $singleton;
BEGIN {
    print "Start.\n";
    $singleton = bless {}, __PACKAGE__;
    print "インスタンスを生成しました。\n";
}
sub getInstance {
    return $singleton;
}
1;
Main.pl
use strict;
use Singleton;

my $obj1 = Singleton->getInstance;
my $obj2 = Singleton->getInstance;

if ($obj1 eq $obj2) {
    print '$obj1と$obj2は同じインスタンスです。', "\n";
}
else {
    print '$obj1と$obj2は同じインスタンスではありません。', "\n";
}
print "End.\n";
Main.plの実行結果
C:\Documents and Settings\dp\Singleton>perl main.pl
Start.
インスタンスを生成しました。
$obj1と$obj2は同じインスタンスです。
End.

サンプル2

チケット発行などで、ユニークでシーケンシャルな番号を発行したい場合、シングルトンパターン適用が有効です。

以下に、適用しないケースと適用したケースを示します。


Main.pl
use strict;
use TicketMaker;

my $obj1 = TicketMaker->getInstance;
my $obj2 = TicketMaker->getInstance;
print $obj1->getNextTicketNumber, "\n";
print $obj1->getNextTicketNumber, "\n";
print $obj2->getNextTicketNumber, "\n";
print $obj2->getNextTicketNumber, "\n";

TicketMaker.pm(適用しないケース:複数インスタンスが可能)
package TicketMaker;
use strict;

sub getInstance {
    my $class = shift;
    my $self = {};
    $self->{ticket} = 1000;
    return bless $self, $class;
}
sub getNextTicketNumber {
    my $self = shift;
    return $self->{ticket}++;
}
1;
C:\Documents and Settings\dp\Singleton>perl Main.pl
1000
1001
1000
1001

同じ番号のチケットが発行されてしまった。


TicketMaker.pm(シングルトンパターンを適用したケース)
package TicketMaker;
use strict;

my $singleton;
BEGIN {
    my $self = {};
    $self->{ticket} = 1000;
    $singleton = bless $self, __PACKAGE__;
}
sub getInstance {
    return $singleton;
}
sub getNextTicketNumber {
    my $self = shift;
    return $self->{ticket}++;
}
1;
C:\Documents and Settings\dp\Singleton>perl Main.pl
1000
1001
1002
1003

ユニークでシーケンシャルな番号のチケットが発行された。


尚、本コンテンツは、結城先生の以下の本をかなり参考にしています。

Javaでデザインパターンを勉強したい人には、お勧めのご著書です!

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

2008-02-26 有難嬉悲しメモ(2008/02/26)

良い本、まずは一冊目

たぶん、英語リスニング・発音系学習の革命的な本ですよ! コレは!

英語を勉強したいのでしたら、英語に専念するだけでなく日本語も併せて勉強しなければダメですし、それと同時に自分の主体性を見失うことのないように気をつけなければなりません。

怖いくらい通じるカタカナ英語の法則 (ブルーバックス (B-1574))

怖いくらい通じるカタカナ英語の法則 (ブルーバックス (B-1574))

2008-02-26 Perlでファクトリメソッドパターン! (デザインパターン)

Perlでデザインパターン 第4弾(ファクトリメソッドパターン)

ファクトリメソッドパターンとは、スーパークラスで処理の枠組みを定め、サブクラスでその具体的内容を定めるようなデザインパターンです。

なんだ、テンプレートメソッドパターンと同じじゃないか・・・と思ったあなた、さすがです。

だた違うのは、ファクトリメソッドパターンでは、抽象的なインスタンスを作成します。

そして、サブクラスで具象的なインスタンスを実装するのです。


以下のクラス図で示されているようにCreatorクラスのcreateメソッドで抽象メソッドfactoryMethodを利用して抽象的なインスタンスを作成します。

つぎに、具象クラスConreteCreatorでfactoryMethodをオーバーライドします。そのfactoryMethodには、Productクラスを継承したConreteProductオブジェクトが渡されるのです。


ファクトリメソッドパターンとは、抽象クラス(CreatorとProduct)で処理の枠組み(フレームワーク)定め、具象クラス(ConreteCreatorとConreteProduct)具体的な肉付けをするパターンです。


注目すべきは、抽象クラスには一切具象クラスが出て来ないことです。つまり、具象レベルがどのような実装になってもこのフレームワーク(抽象クラス)が使えるということです。


一般的なファクトリメソッドパターンのクラス図
     +---------------------+  Creates    +---------------------+                    
     |  Creator            |------------>| Product             |                    
     +---------------------+             +---------------------+                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
     |  create             |             |  method1            |                    
     |  factoryMethod      |             |  method2            |                    
     |                     |             |  method3            |                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
                #                                   #                               
                |                                   |                               
                |                                   |                               
                |                                   |                               
     +----------+----------+  Creates    +----------+----------+                    
     | ConreteCreator      |------------>| ConreteProduct      |                    
     +---------------------+             +---------------------+                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
     | factoryMethod       |             | method1             |                    
     |                     |             | method2             |                    
     |                     |             | method3             |                    
     +---------------------+             +---------------------+                    

サンプル

IDカードを作るサンプルです。

詳しくは、『増補改訂版Java言語で学ぶデザインパターン入門』に書かれています。


サンプルのクラス図
     +---------------------+  Creates    +---------------------+                    
     | Factory             |------------>| Product             |                    
     +---------------------+             +---------------------+                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
     |  create             |             |  use                |                    
     |  createProduct      |             |                     |                    
     |  registerProduct    |             |                     |                    
     |                     |             |                     |                    
     +---------------------+             +---------------------+                    
                #                                   #                               
                |                                   |                               
                |                                   |                               
                |                                   |                               
     +----------+----------+  Creates    +----------+----------+                    
     | IDCardFactory       |------------>| IDCard              |                    
     +---------------------+             +---------------------+                    
     | owners              |             | owner               |
     +---------------------+             +---------------------+                    
     | createProduct       |             | use                 |                    
     | registerProduct     |             | getOwner            |                    
     +---------------------+             +---------------------+                    
Product.pm
package Product;
use strict;

sub use { die "オーバーライド必須"; }
1;
Factory.pm
package Factory;
use strict;

sub create {
    my $self = shift;
    my $owner = shift;
    my $p = $self->createProduct($owner);
    $self->registerProduct($p);
    return $p;
}
sub createProduct { die "オーバーライド必須"; }
sub registerProduct { die "オーバーライド必須"; }
1;
IDCard.pm
package IDCard;
use strict;
use base 'Product';

sub new {
    my $class = shift;
    my $self = {};
    $self->{owner} = shift;
    print "$self->{owner}のカードを作ります。\n";
    return bless $self, $class;
}
sub use {
    my $self = shift;
    print "$self->{owner}のカードを使います。\n";
}
sub getOwner {
    my $self = shift;
    return $self->{owner};
}
1;
IDCardFactory.pm
package IDCardFactory;
use strict;
use IDCard;
use base 'Factory';

sub new {
    my $class = shift;
    my $self = {};
    $self->{owners} = [];
    return bless $self, $class;
}
sub createProduct {
    my $self = shift;
    my $owner = shift;
    return IDCard->new($owner);
}
sub registerProduct {
    my $self = shift;
    my $product = shift;
    push @{$self->{owners}}, $product->getOwner();
}
1;
Main.pl
use strict;
use IDCardFactory;

my $factory = IDCardFactory->new;
my $card1 = $factory->create('まちゃ');
my $card2 = $factory->create('やちゅ');
my $card3 = $factory->create('ヒロ');
$card1->use();
$card2->use();
$card3->use();
Main.plの実行結果
C:\Documents and Settings\dp\FactoryMethod>perl main.pl
まちゃのカードを作ります。
やちゅのカードを作ります。
ヒロのカードを作ります。
まちゃのカードを使います。
やちゅのカードを使います。
ヒロのカードを使います。

尚、本コンテンツは、結城先生の以下の本をかなり参考にしています。

Javaでデザインパターンを勉強したい人には、お勧めのご著書です!

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

2008-02-25 有難嬉悲しメモ(2008/02/25)

2008-02-25 FileHandleモジュールの使い方メモ

open関数やclose関数を使わず、FileHandleモジュールを使用するとオブジェクト風にファイルI/Oが出来ます。


FileHandleモジュールを使ったサンプルのメモ
    use FileHandle;

    $fh = new FileHandle;
    if ($fh->open("< File.txt")) {
        print <$fh>;
        $fh->close;
    }
    $fh = new FileHandle "> File2.txt";
    if (defined $fh) {
        print $fh "testx\n";
        $fh->close;
    }
    $fh = new FileHandle "File.txt", "r";
    if (defined $fh) {
        print <$fh>;
        undef $fh;
    }
    $fh = new FileHandle "File2.txt", O_WRONLY|O_APPEND;
    if (defined $fh) {
        print $fh "testy\n";
        undef $fh;
    }

2008-02-24 有難嬉悲しメモ(2008/02/24)

2008-02-24 Perlでテンプレートメソッドパターン! (デザインパターン)

Perlでデザインパターン 第3弾(テンプレートメソッドパターン)

テンプレートメソッドパターンとは、スーパークラスで処理の枠組みを定め、サブクラスでその具体的内容を定めるようなデザインパターンです。

以下のクラス図で示されているようにAbstractClassのtemplateMethodでアルゴリズムを記述し、ConcreteClassのmethod1等で具体的内容を記述する。

ちなにみ、AbstractClassは抽象(アブストラクト)クラスで、ConcreteClassは具象(コンクリート)クラスといいます。


一般的なテンプレートメソッドパターンのクラス図
     +---------------------+
     | AbstractClass       |
     +---------------------+
     |                     |
     +---------------------+
     |  method1            |
     |  method2            |
     |  templateMethod     |
     |                     |
     +---------------------+
                #
                |
                |継承
                |
     +----------+----------+
     | ConcreteClass       |
     +---------------------+
     |                     |
     +---------------------+
     | method1             |
     | method2             |
     |                     |
     |                     |
     +---------------------+
サンプル

以下は、テンプレートメソッドパターンを利用した、文字や文字列を五回繰り返して表示するサンプルです。

まず、スーパークラスAbstractDisplayでAbstractメソッド(open、print、close)を使ってtemplateMethodであるdisplayで、アルゴリズムを定義します。

つぎに、サブクラスのCharDisplayとStringDisplayでそのAbstractメソッドを各々オーバライドします。


サンプルのクラス図
                        +---------------------+
                        | AbstractDisplay     |
                        +---------------------+
                        |                     |
                        +---------------------+
                        |  open               |
                        |  print              |
                        |  close              |
                        |  display            |
                        +---------------------+
                                   #            
                                   |            
                +------------------+-------------------+ 
                |                                      | 
     +----------+----------+                +----------+----------+ 
     | CharDisplay         |                | StringDisplay       | 
     +---------------------+                +---------------------+ 
     |                     |                |                     | 
     +---------------------+                +---------------------+ 
     | open                |                | open                | 
     | print               |                | print               | 
     | close               |                | close               | 
     |                     |                | printLine           | 
     +---------------------+                +---------------------+ 
AbstractDisplay.pm
package AbstractDisplay;
use strict;

sub open { die "オーバーライド必須"; }
sub print { die "オーバーライド必須"; }
sub close { die "オーバーライド必須"; }
sub display {
    my $self = shift;
    $self->open;
    for (my $i = 0; $i < 5; $i++) {
        $self->print;
    }
    $self->close;
}
1;
CharDisplay.pm
package CharDisplay;
use strict;
use base 'AbstractDisplay';

sub new {
    my $class = shift;
    my $self = {};
    $self->{ch} = shift;
    return bless $self, $class;
}
sub open {
    my $self = shift;
    print "<<";
}
sub print {
    my $self = shift;
    print "$self->{ch}";
}
sub close {
    my $self = shift;
    print ">>\n";
}
1;
StringDisplay.pm
package StringDisplay;
use strict;
use base 'AbstractDisplay';

sub new {
    my $class = shift;
    my $self = {};
    $self->{string} = shift;
    $self->{width} = length($self->{string});
    return bless $self, $class;
}
sub open {
    my $self = shift;
    $self->printLine;
}
sub print {
    my $self = shift;
    print "|$self->{string}|\n";
}
sub close {
    my $self = shift;
    $self->printLine;
}
sub printLine {
    my $self = shift;
    print "+";
    for (my $i = 0; $i < $self->{width}; $i++) {
        print "-";
    }
    print "+\n";
}
1;
Main.pl
use strict;
use CharDisplay;
use StringDisplay;

my $d1 = CharDisplay->new('H');
my $d2 = StringDisplay->new('Hello, World.');
my $d3 = StringDisplay->new('こんにちは。');
$d1->display;
$d2->display;
$d3->display;
Main.plの実行結果
C:\Documents and Settings\TemplateMethod>perl main.pl
<<HHHHH>>
+-------------+
|Hello, World.|
|Hello, World.|
|Hello, World.|
|Hello, World.|
|Hello, World.|
+-------------+
+------------+
|こんにちは。|
|こんにちは。|
|こんにちは。|
|こんにちは。|
|こんにちは。|
+------------+

尚、本コンテンツは、結城先生の以下の本をかなり参考にしています。

Javaでデザインパターンを勉強したい人には、お勧めのご著書です!

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

2008-02-23 基本的な語順

基本的な語順

以下の順番に文を組み立てると、とても読みやすい文になります。

  1. 「時」を表す語句
  2. 「場所」を表す語句(で格)
  3. 「主格」を表す語句(が格)
  4. 「相手」を表す語句(に格)
  5. 「対象」を表す語句(を格)
  6. 動詞(述語)
サンプル

「先週 府中で ヒロが ヤスに カレー料理を ご馳走した」


まとめ

「いつ どこで だれが だれに なにを した」が文の基本!


参考:「日本語てにをはルール―知っているようで知らない

2008-02-232 僕はうなぎです

主語Aと述語Bが対応している「AはBです」という構造の文を「コピュラ文」といいます。

しかし、以下のようなものは「コピュラ文」でなく「うなぎ文」や「こんにゃく文」といいます。

文は、「うなぎ文」や「こんにゃく文」にならないように、正確な「コピュラ文」になるようにすると、分かりやすくなります。


参考:「日本語てにをはルール―知っているようで知らない

2008-02-20 ネットを休みます

まだ、ネタは少しあるのだけれど、ここのところ精神的になにか、おかしい自分・・・。

しばらく、ネットを休みます。

でも、3〜4日で復帰すると思います。いままでの経験から・・・。

では、それまでサヨウナラ!

2008-02-19 有難嬉悲しメモ(2008/02/19)

2008-02-19 WebページからIEのホームページ(レジストリ)を変更する

以下のようにIEのセキュリティ設定で、一箇所有効にするとWEBからレジストリ変更が出来ます。


以下のサンプルは、IEのホームページ(起動直後のページ)をサンプルソースページへ変更します。

サンプルソースページ以外のページへのカスタマイズは、「document.location」を任意URLへ替えてください。


サンプルソース
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
<title>WebページからIEのホームページ(レジストリ)を変更する</title>
</head>
<body>
<script language="VBScript">
chg_HomePage()
Function chg_HomePage()
    If msgbox("IEのホームページを現ページに変更します。よろしいですか?",1) = 1 then
        Set WshShell=CreateObject("WScript.Shell")
       'RegReadメソッドで、レジストリ内の指定キー(現ホームページ)の設定値を取得する
        msgbox("元のホームページ -> " & WshShell.RegRead("HKCU\Software\Microsoft\Internet Explorer\Main\Start Page"))
        'レジストリ内の指定キーの設定値を第2引数に指定された値で更新。第3引数には、レジストリに格納する値のデータ型を指定する
        WshShell.RegWrite "HKCU\Software\Microsoft\Internet Explorer\Main\Start Page",document.location, "REG_SZ"
        msgbox("変更後のホームページ -> " & WshShell.RegRead("HKCU\Software\Microsoft\Internet Explorer\Main\Start Page"))
        Set WshShell = Nothing
    End If
End Function
</script>
</body>
</html>

留意点

上記設定は、インターネットでは、お奨めしません。イントラネットでご利用ください。

また、レジストリ操作なので、操作を誤ると、Windowsが正常に動作しなくなったりします。自己責任で行ってください。

2008-02-18 有難嬉悲しメモ(2008/02/18)

2008-02-18 VB2005でのゼロ除算の留意点

割り込みのテストの時にゼロ除算を良く使用します。

しかし、VB2005では以下のようなしてもゼロ除算割り込みが発生しないのです。

これは、「/」を「\」に変更すると割り込みが発生するようになります。

ちなみに、「\」は整数除算算術演算子で、「/」は除算算術演算子という。

また、余りを求めるには、Mod演算子を使用する。


割り込みが発生しない
Try
    Dim aa = 0
    Dim bb = 4 / aa
 Catch ex As Exception
    MsgBox("Exception発生")
End Try
割り込みが発生する
Try
    Dim aa = 0
    Dim bb = 4 \ aa
 Catch ex As Exception
    MsgBox("Exception発生")
End Try

2008-02-17 有難嬉悲しメモ(2008/02/17)

当番長さん達に「なぜか、毎日がなんとなく不安です」と言うと、不安でない人などいないと言われ、すこし安心しました。不安は次から次えと出てくるそうです。確かにそーですね。

2008-02-17 Perlでアダプターパターン! (デザインパターン)

Perlでデザインパターン 第2弾(アダプターパターン)

まず、オブジェクト指向の基礎とアダプターパターンついては、以下のリンクを参照してください。

また、Perlでのオブジェクト指向については、以下のリンクを参照してください。


アダプターサンプルのクラス図
       Client
     +-------------+
     | Main        |
     +-------------+
     |             |
     +-------------+
     |             |
     +-------------+
            |
            |
            | 使用:関連
            v
     +-------------+            +-------------+            +------------------+
     | Target      |            | Adapter     |            | Adaptee          |
     +-------------+            +-------------+            +------------------+
     |             |#-----------| adaptee     |o---------->|                  |
     +-------------+ 継承:汎化 +-------------+ 委譲:集約 +------------------+
     | request()   |            | request()   |            | specialRequest() |
     +-------------+            +-------------+            +------------------+

では、以下で、アダプターパターンでのJavaソースとそれをPerlでリメイクしたソースとの違いをご確認ください。

尚、Javaのソースは「オブジェクト指向 WITH JAVA:アダプターパターン」のと同じです。


アダプターサンプルのソース
ターゲットクラス(やりたいことを抽象レベルで考えたクラスです)

Target.java

public abstract class Target {
    public abstract void printEm();
    public abstract void printStrong();
}

Target.pm

package Target;
use strict;
    sub printEm{die "オーバーライド必須";}
    sub printStrong{die "オーバーライド必須";}
1;

アダプティ−クラス(やりたいことが似ている具象クラスです)

Adaptee.java

public class Adaptee {
    private String string;
    public Adaptee(String string) {
        this.string = string;
    }
    public void showWithParen() {
        System.out.println("(" + string + ")");
    }
    public void showWithAster() {
        System.out.println("*" + string + "*");
    }
    public void showWithSemicolon() {
        System.out.println(";" + string + ";");
    }
    public void showWithPercent() {
        System.out.println("%" + string + "%");
    }
}

Adaptee.pm

package Adaptee;
use strict;
    sub  new {
        my $class = shift;
        my $string = shift;
        return bless {string => $string}, $class;
    }
    sub showWithParen {
        my $self = shift;
        print "\($self->{string}\)", "\n";
    }
    sub showWithAster {
        my $self = shift;
        print "\*$self->{string}\*", "\n";
    }
    sub showWithSemicolon {
        my $self = shift;
        print "\;$self->{string}\;", "\n";
    }
    sub showWithPercent {
        my $self = shift;
        print "\%$self->{string}\%", "\n";
    }
1;

アダプタークラス(ターゲットクラスとアダプティ−クラスを繋ぐ(適合)クラスです。ターゲットクラスを継承し、アダプティ−クラスを委譲します)

Adapter.java

public class Adapter extends Target {
    private Adaptee adaptee;
    public Adapter(String string) {
        this.adaptee = new Adaptee(string);
    }
    public void printEm() {
        adaptee.showWithParen();
    }
    public void printStrong() {
        adaptee.showWithAster();
    }
}

Adapter.pm

package Adapter;
use strict;
use base 'Target';
use Adaptee;
    sub  new {
        my $class = shift;
        my $string = shift;
        my $adaptee = Adaptee->new($string);
        return bless {adaptee => $adaptee}, $class;
    }
    sub printEm {
        my $self = shift;
        $self->{adaptee}->showWithParen;
    }
    sub printStrong {
        my $self = shift;
        $self->{adaptee}->showWithAster;
    }
1;

メインクラス

Main.java

public class Main {  //client
    public static void main(String[] args) {
        Target p = new Adapter("Hello");
        p.printEm();
        p.printStrong();
    }
}

Main.pl

use strict;
use Adapter;
        my $p = Adapter->new("Hello");
        $p->printEm();
        $p->printStrong();

2008-02-16 有難嬉悲しメモ(2008/02/16)

いい大人で、小学生調の文章になっていますが、「有難嬉悲しメモ」とは、「有り難かったです。」「嬉しかったです。」「悲しかったです。」という3つの結語の文章をほぼ毎日書くメモのことです。


実は、コレ、ブログを更新の切り札になりますよ。その日一日で「有り難かったこと」「嬉しかったこと」「悲しかったこと」を書くだけです。どんな人でも、一つぐらいは、ありますよね! 上の3つ!

2008-02-16 Perlでイテレータパターン! (デザインパターン)

Perlでデザインパターン 第1弾(イテレータパターン)

かつて、Java言語でデザインパターンを勉強したメモが以下のリンクにあります。

今回、Perlでリメイクしてみました。第一弾は、「Perlでイテレータパターン!」です。

尚、オブジェクト指向の基礎とイテレータパターンの解説は、上記のリンクを読んでください。

また、Perlでのオブジェクト指向の解説は下記のリンクを読んでください。


イテレータサンプルのクラス図
     +---------------------+                 +-------------------+
     | Aggregate           |---------------->| Iterator          |
     +---------------------+                 +-------------------+
     |                     |                 |                   |
     |  iterator()         |                 | hasnext()         |
     |                     |                 | next()            |
     |                     |                 |                   |
     +---------------------+                 +-------------------
                #                                      #
                |                                      |
                |                                      |継承
                |                                      |
     +----------+----------+                 +---------+---------+
     | 部品棚              |<---------------O| 部品イテレータ    |
     +---------------------+                 +-------------------+
     | buhins              |                 | aggregate         |
     | last                |                 +-------------------+
     +---------------------+                 |                   |
     | addBuhin()          |                 | hasnext()         |
     |                     |                 | next()            |
     |                     |                 |                   |
     +---------------------+                 +-------------------+
                O
                |
                |集約
                V
     +----------+----------+
     | 部品                |
     +---------------------+
     | name                |
     +---------------------+
     | getname()           |
     |                     |
     +---------------------+

イテレータサンプルのプログラムソース

では、以下で、イテレータパターンのJavaとPerlでのソースの違いをご確認ください。

尚、Javaのソースは「オブジェクト指向 WITH JAVA」のと同じです。

Aggregateインターフェイス

Aggregate.java

public interface Aggregate {
    public abstract Iterator iterator();
}

Aggregate.pm

package Aggregate;
use strict;
sub iterator{die "オーバーライド必須";}
1;

Iteratorインターフェイス

Iterator.java

public interface Iterator {
    public abstract boolean hasNext();
    public abstract Object next();
}

Iterator.pm

package Iterator;
use strict;
sub  hasNext{die "オーバーライド必須";}
sub  next{die "オーバーライド必須";}
1;

部品イテレータクラス

BuhinIterator.java

public class BuhinIterator implements Iterator {
    private Buhindana buhindana;
    private int index;
    public BuhinIterator(Buhindana buhindana) {
        this.buhindana = buhindana;
        this.index = 0;
    }
    public boolean hasNext() {
        if (index < buhindana.getLength()) {
            return true;
        } else {
            return false;
        }
    }
    public Object next() {
        Buhin buhin = buhindana.getBuhinAt(index);
        index++;
        return buhin;
    }
}

BuhinIterator.pm

package BuhinIterator;
use strict;
use base 'Iterator';
    sub new {
        my $class = shift;
        my $buhindana = shift;
        return bless { buhindana => $buhindana, index => 0} , $class;
    }
    sub hasNext {
       my $self = shift;
       if ($self->{index} < $self->{buhindana}->getLength()) {
            return 1;
        } 
        else {
            return 0;
        }
    }
    sub  next {
        my $self = shift;
        my $buhin = $self->{buhindana}->getBuhinAt($self->{index});
        $self->{index}++;
        return $buhin;
    }
1;

部品棚クラス

Buhindana.java

public class Buhindana implements Aggregate {
    private Buhin[] buhins;
    private int last = 0;
    public Buhindana(int maxsize) {
        this.buhins = new Buhin[maxsize];
    }
    public Buhin getBuhinAt(int index) {
        return buhins[index];
    }
    public void addBuhin(Buhin buhin) {
        this.buhins[last] = buhin;
        last++;
    }
    public int getLength() {
        return last;
    }
    public Iterator iterator() {
        return new BuhinIterator(this);
    }
}

Buhindana.pm

package Buhindana;
use strict;
use base 'Aggregate';
use BuhinIterator;
    sub  new {
        my $class = shift;
        return bless {buhins => [], last =>0}, $class
    }
    sub getBuhinAt {
        my $self = shift;
        my $index = shift;
        return $self->{buhins}[$index];
    }
    sub addBuhin {
        my $self = shift;
        my $buhin = shift;
        $self->{buhins}[$self->{last}] = $buhin;
        $self->{last}++;
    }
    sub getLength {
        my $self = shift;
        return $self->{last};
    }
    sub iterator {
        my $self = shift;
        return BuhinIterator->new($self);
    }
1;

部品クラス

Buhin.java

public class Buhin {
    private String name = "";
    public Buhin(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
}

Buhin.pm

package Buhin;
use strict;
    sub  new {
        my $class = shift;
        my $name = shift;
        return bless {name => $name}, $class;
    }
    sub getName {
        my $self = shift;
        return $self->{name};
    }
1;

メインクラス

Main.java

public class Main {
    public static void main(String[] args) {
        Buhindana buhindana = new Buhindana(4);
        buhindana.addBuhin(new Buhin("CPU"));
        buhindana.addBuhin(new Buhin("メモリ"));
        buhindana.addBuhin(new Buhin("マザーボード"));
        buhindana.addBuhin(new Buhin("ハードディスク"));
        Iterator it = buhindana.iterator();
        while (it.hasNext()) {
            Buhin buhin = (Buhin)it.next();
            System.out.println("" + buhin.getName());
        }
    }
}

Main.pl

use strict;
use Buhindana;
use Buhin;
        my $buhindana = Buhindana->new;
        $buhindana->addBuhin(Buhin->new("CPU"));
        $buhindana->addBuhin(Buhin->new("メモリ"));
        $buhindana->addBuhin(Buhin->new("マザーボード"));
        $buhindana->addBuhin(Buhin->new("ハードディスク"));
        my $it = $buhindana->iterator();
        while ($it->hasNext()) {
            my $buhin = $it->next();
            print $buhin->getName(), "\n";
        }

最後に本コンテンツの元は、結城先生のご著書「デザインパターン入門」を大変参考にしています。いつもありがとうございます。本格的にデザインパターンを勉強するのであれば、絶対に「買い」です!

増補改訂版Java言語で学ぶデザインパターン入門

増補改訂版Java言語で学ぶデザインパターン入門

2008-02-15 有難嬉悲しメモ(2008/02/16)

それから、デザパタ本ですが、一時はどうしても見つからず、普段行かない会社の事務所までいって探しました(普段は出向先)。

事務所にもなく、その帰り、残念な思いでいると、ふと、デザパタ本をしまった場所を思い出したのです。

家に着いて、その場所を見たらあったのです。神様、仏様、結城様、ありがとう!

2008-02-15 qwの勘違い

qwの「w」は、ダブルクォーティションの「w」かと勘違いしやすいですね。

「w」は、たぶんWORDの「w」で、qwは、ワードをスペースデリミタでシングルクォーティションします。

my $bbb = "BBB";
my @xxx = qw(111 222 AAA $bbb); # @xxx = ('111', '222', 'AAA', '$bbb')と等価

したがって、$bbbは、展開されない。

2008-02-15 配列スライスとハッシュスライス

スライス(slice)とは、薄く切るという意味で、配列の中からインデックスを指定して要素を切り出します。


配列スライスサンプル
my @week = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat') ;
my @weekday = @week[1..5];
print "@weekday", "\n"; # 「Mon Tue Wed Thu Fri」を表示

ハッシュスライスサンプル
my %hash = ('Sun'=>'日', 'Mon'=>'月', 'Tue'=>'火', 'Wed'=>'水', 'Thu'=>'木', 'Fri'=>'金', 'Sat'=>'土');
my @weekend = @hash{'Sun', 'Sat'};
print "@weekend", "\n"; # 「日 土」を表示

2008-02-15 ダブルクォーティション文字列内での配列変数の展開

まず、配列変数をprintすると要素がくっ付いて表示されます。

また、スカラー値と連結すると要素数を表示します。

では、ダブルクォーティション文字列内では、どうなるかというと、要素がスペースデリミタで表示されます。

実は、スペースデリミタは、「$"」変数の値によって自由に変えられるのです。

my @xxx = qw(111 222 AAA);
print @xxx, "\n";       # 要素がくっ付いて表示
print "@xxx", "\n";     # 要素がスペースデリミタで表示
print 3 .  @xxx, "\n";  # スカラー値と連結すると要素数を表示
$" = "macha";           # デリミタを変更
print "@xxx", "\n";     # 要素がデリミタがmachaになる
処理結果
C:\Documents and Settings\xxx>perl hairetu.pl
111222AAA
111 222 AAA
33
111macha222machaAAA

2008-02-14 有難嬉悲しメモ(2008/02/14)

2008-02-14 JavaScriptのlocation.hrefの謎の動き

JavaScriptの「location.href」は、現ページのURLを保持しています。

そして普通は、「location.href」へ他ページのURLを代入して、そのページに遷移するのに使用します。

では、空文字列を代入すると、どうなるでしょうか?…


答え:

現ページのあるフォルダのURLへ遷移しようとするのです。

また、そのフォルダにindex.htmlやindex.cgiが関連付けられているとそのページを表示するのです(ある意味、謎の動き)。

あと、「location.href」へURLを代入した後、alertで「location.href」を見ると代入したURLでなく現ページのままなのです(これは仕様かな)。

2008-02-13 有難嬉悲しメモ(2008/02/13)

2008-02-13 runtimeStyleについてのメモ

runtimeStyleについてのメモです。

runtime style オブジェクト(element.runtimeStyle)を通して設定されたスタイルは、他の全ての CSS プロパティ設定の値を上書きします。runtimeStyle オブジェクトは別に保持されているので、これを変更しても他の CSS 設定には干渉しません。たとえば、次のシーケンスを考えます。

element.style.color = "blue"; // element is now blue
…
element.runtimeStyle.color = "red"; // element is now red
…
element.runtimeStyle.color = ""; // element is blue again

runtimeStyle に加えた変更が、要素の他の CSS 設定にどのように上書きするか注目してください。ただし、オブジェクトが削除されると、最初の CSS 値が再適用されます。

http://www.microsoft.com/japan/msdn/columns/dude/dude050399.aspx

IEのruntimeStyleオブジェクトは、オブジェクトthisでもスタイルを適用することができる。

しかし、Fierfoxでは、スクリプトが無応答終了する。

2008-02-13 ClickオンShowアンドhide

クリックするとリンクが現れ(Show)、そして、再度クリックすると消える(hide)ヤツです。

出尽くしたサンプルかもしれませんが、何かの参考になれば幸いです。

<html>
<head>
<title>ClickオンShowアンドhide</title>
<script type="text/javascript">
<!--
    function ShowAndhide(id) {
        if(document.getElementById){
           if(document.getElementById(id).style.display == "none") {
              document.getElementById(id).style.display  = "block";
           }
           else {
              document.getElementById(id).style.display  = "none";
           }
        }
    }
// -->
</script>
</head>
<body>
<ul>
<li><a href='javascript:void(0);' onclick='ShowAndhide("label01"); return false;'>ポータル</a></li>
    <div id='label01' style='display:none;'>
    <ul>
    <li><a href='http://www.google.co.jp/' >グーグル</a></li>
    <li><a href='http://www.yahoo.co.jp/' >ヤフー</a></li>
    </ul>
    </div>
</ul>
</body>
</html>

2008-02-12 有難嬉悲しメモ(2008/02/12)

2008-02-12 javascript:void(0)について

リンクのa要素のhref属性に「javascript:void(0)」を指定すると、リンクを無効にすることができます。

また、その代わりにonclick属性で「xxx()」を指定して、リンク処理を行うこともできます。

その時の留意点として、「return false;」指定すると何かと吉です。

(onclickのときは、「javascript:void(0)」だけでは無効にならず、「return false;」で完全無効になる?)

<a href="javascript:void(0)" onclick="xxx(); return false;">

a要素としてのリンク機能とonclickでの処理が干渉して、謎の動きをします。

上記のようにonclickに「return false;」を追加することにより、a要素としてのリンク機能を完全無効(謎の動きを封じる)にするものと思われます。

2008-02-11 有難嬉悲しメモ(2008/02/11)

2008-02-11 「1 while s///」とはなにか?

昨日、ご紹介したスクリプトの中に以下があったと思います。

 1 while $wk =~ s/\([^()]*\)//g; # 関数系を弾く

これは、SQLのSelect文の選択項目のところに以下のような関数が使用された場合、それ弾いています。

select MAX(ISNULL(aa,'0')) AS bb from aabb_tbl 

「1 while s///」の説明は、以下にありました。

ここで,「1 while s///」というのは,「while (s///) {1}」と書くのと等しいです。

置換(s///)は成功すれば置換した数(この場合1)を,失敗すれば0を返すので,上の例では置換が成功する限り{ }の中の「1」を実行し続けます。実際には「1」は実行しても何も起こりません。

なので,「1 while s///」は置換ができる限りはそれを続け,置換ができなくなればそれで終了する,という関数になります。

http://www.bi.a.u-tokyo.ac.jp/~mizuki/personal/Research/PerlOneLiner.html

たとえば、以下の場合などに使います。

入れ子を許した括弧内を削除する

1 while $str =~ s/\([^()]*\)//g;

http://www.din.or.jp/~ohzaki/regex.htm#RemoveNestedParen

まず、正規表現括弧パターン「\([^()]*\)」をNULL置換した後に、whileで再帰的にそれを行い、マッチしなくなるとwhileを抜ける。

2008-02-10 有難嬉悲しメモ(2008/02/10)

2008-02-10 SQL-SELECT文からPerl-HASH関数へ(Select2Hash)

PerlからOLEモジュールを使って、SQLServerからデータをSELECTするときに、そのデータを、行は配列、列はハッシュとして、Perlでの「配列のハッシュ」に格納すると取得データのアクセスが便利です。

以下のSelect2Hash関数は、そのような関数です。

use strict;
my @result = &Select2Hash("SELECT UserName, UserTel FROM UserTable");
for (my $i = 0; $i <= $#result; $i++){
    print $result[$i]{UserName}, "\n";
    print $result[$i]{UserTel}, "\n";
}
sub Select2Hash {
# 本ルーチンによるSELECT文フォーマット制限
# 1,SELECTとFROMを必ず同一行に記述する。(SELECT aaa, bbb, ccc FROM……)
# 2,選択項目でエイリアスがある時は必ずASキーワードを使用する(SELECT X.aaa AS xxx, ……)
# 3,選択項目は、アスター「*」は不可(選択項目はハッシュキーになるため)。
use Win32::OLE;
use Win32::OLE::Variant; # これがないと日付型系データが上手く取得できない
use Win32::OLE::Const 'Microsoft ActiveX Data Objects 2.0 Library';# adUseClient等が宣言されている
Win32::OLE->Option(Warn => 3); # エラー時にエラーメッセージを出力後、本プロセスが終了する
# 以下の接続情報を初期コーディングする。
my $server='';  # DBServer
my $db='';      # DBName
my $id='';      # ID
my $ps='';      # Password

    my ($Sql) = @_; # 引数取得(SQL文のみ)

    # DB接続
    my $objDB=Win32::OLE->new("ADODB.Connection");
    my $connStr="Provider=sqloledb;".
                "Data Source=$server;".
                "Initial Catalog=$db;".
                "User ID=$id;".
                "Password=$ps;"; #(WINDOWS認証の時は『Integrated Security=SSPI;』を付加する)
    $objDB->Open($connStr);
    if ($objDB->{Errors}->{Count}) {
        die "cannot connect '$connStr'";
    }

    # Recordsetを作成
    my $rs=Win32::OLE->new("ADODB.Recordset");

    # RecordCountを返すようにする
    $rs->{CursorLocation} = adUseClient; 

    # SQL文からハッシュキーにするための選択項目を配列に取得する。
    $Sql =~ /SELECT(.*?)FROM/i;     # ?の最小マッチにするのは、Where文にFROMが入る可能性があるため
    my $wk = $1;

    1 while $wk =~ s/\([^()]*\)//g; # 関数系を弾く
    $wk = ',' . $wk;                # 先頭に「,」を付加する
    $wk =~ s/,[^,]*? AS/,/gi;       # AS系を弾く
    $wk =~ s/^,//;                  # 先頭の「,」を削除する
    $wk =~ s/ //g;                  # スペースをつめる

    my @selectItem = split(/,/, $wk);

    # SELECTしたデータを、行は配列へ列は選択項目がキーのハッシュへ格納する。
    my %data;
    my @AoA;
    my $ref;
    $rs->Open($Sql, $objDB);
    while(!$rs->EOF and $rs->{RecordCount}!=0){
        foreach my $scalar (@selectItem) {
             $data{$scalar} = $rs->{Fields}->{$scalar}->{Value};
        }
        $rs->MoveNext();
        $ref = { %data };
        push @AoA, $ref;
    }
    $rs->Close();

    # DB切断
    $objDB->Close();
    return @AoA;
}
留意点:本ルーチンによるSELECT文フォーマット制限

2008-02-09 有難嬉悲しメモ(2008/02/09)

2008-02-09 ファイル分割のサンプルスクリプト

たとえば、記事数が多くなり、サイズが大きくなったhtmlファイルがあったとします。

これを記事毎のhtmlファイルに分割したい場合、以下のサンプルが参考になると思います。


このサンプルは、perlnote.htmファイル内でのh4要素からつぎのh4要素の前までの行データ(記事データ)を各々のファイルへ出力します。

つまり、h4要素単位に分割された内容のファイルがh4要素の数分作成されるわけです。


ファイル名は、「perlnote」プラス「該当h4要素のid」プラス「.htm」とします。

また、分割ファイルにはヘッダーとフッターを付加します。


尚、ヘッダーとフッターのファイルは予め用意します。

しかし、ヘッダーのtitle要素とh1要素には、該当h4要素の内容を実行時にコピーします。


サンプルソース
use strict;
# 宣言
my ($fileheadx, $fnm, $xx, $wk, $fileheader,$filefooter);

# ファイル読み込みデリミタをなしにする(ファイル全体読み込みモードにする)
$wk = $/;
$/ = undef;

# HTMLファイルヘッダー保存
open(FH, "h_perlnote.htm") || die "open err", "(h_perlnote.htm)";
$fileheader = <FH>;
close(FH);

# HTMLファイルフッター保存
open(FH, "f_perlnote.htm") || die "open err", "(f_perlnote.htm)";
$filefooter = <FH>;
close(FH);

#ファイル読み込みデリミタを普通(行単位)にする。
$/ = $wk;

open (IN, "perlnote.htm") || die "open err", "(perlnote.htm)";
open (OUT, ">dmy.tmp") || die "open err", "(dmy.tmp)";
while ($xx = <IN>) {
    if ($xx =~ /<h4 id="(.*?)"/) {
        print OUT $filefooter, "\n";
        close OUT;
        $fnm = "perlnote" . $1 . ".htm" , "\n"; # ファイル名作成
        $xx =~ /<h4.*>(.*)<\/h4>/i;
        $wk = $1;
        $fileheadx = $fileheader;
        # title要素とh1要素には、該当h4要素の内容をコピーする。
        $fileheadx =~ s/<title.*<\/title>/<title>$wk<\/title>/i; 
        $fileheadx =~ s/<h1.*<\/h1>/<h1>$wk<\/h1>/i;
        open (OUT, ">$fnm") || die "open err", "($fnm)";
        print OUT $fileheadx, "\n";
    }
    print OUT $xx;
}
print OUT $filefooter, "\n";
close OUT;
close IN;

2008-02-08 有難嬉悲しメモ(2008/02/08)

2008-02-08 Perlでの継承とは?

普通、オブジェクトのクラスは、他のオブジェクトのクラスを継承することができます。

クラスの継承ができるということは、オブジェクトの抽象化と具象化に繋がり、結果的にオブジェクトの部品化を促進します。


Perlでのオブジェクトのクラスも継承ができます。

Perlでの継承は、baseプラグマを使用します。


以下のサンプルは、testx01.plが継承なしで、testx02.plが継承ありのケースです。

継承ありのtestx02.plでは、DateString2クラス(サブクラス)を使用していますが、このクラスはDateStringクラス(スーパークラス)を継承しています。


見た目、DateString2クラスのコンストラクタnewを起動していますが、実はDateString2クラスにはコンストラクタnewはありません。

これは、継承したDateStringクラスのコンストラクタnewを起動しているのです。


また、DateStringクラスとDateString2クラスには同じ名前のto_stringメソッドがあります。

to_stringメソッドは、コンストラクタnewと違い、DateString2クラス自身のto_stringメソッドが起動されます。


つまり、スーパークラスのメソッドの上にサブクラスのメソッドが乗ってしまったのです。

これをオーバーライドという。


testx01.pl
#!/usr/bin/perl
use strict;
use DateString;

my $date = DateString->new;
print $date->to_string;

testx02.pl
#!/usr/bin/perl
use strict;
use DateString2;

my $date = DateString2->new;
print $date->to_string;

DateString.pm
package DateString;
use strict;
sub new {
    my $class = shift; # 第一引数は、クラス名が渡される。
    my $time = shift || time();
    return bless { time => $time }, $class; # blessしたリファレンスを返す。
}
sub to_string {
    my $self = shift;
    return scalar localtime $self->{time};
}
1;

DateString2.pm
package DateString2;
use base DateString; # DateStringクラスの継承
use strict;
use constant DATE_FORMAT => '%04d/%02d/%02d %02d:%02d:%02d (%s)';

sub to_string {
    my $self = shift;
    my @loaclt = localtime $self->{time};
    return sprintf DATE_FORMAT,
           $loaclt[5] + 1900,
           $loaclt[4] + 1,
           $loaclt[3],
           $loaclt[2],
           $loaclt[1],
           $loaclt[0],
           (qw(日 月 火 水 木 金 土))[$loaclt[6]];
}
1;

処理結果
C:\Documents and Settings\xxx\DateString>perl testx01.pl
Fri Feb  8 22:23:41 2008
C:\Documents and Settings\xxx\DateString>perl testx02.pl
2008/02/08 22:23:47 (金)

2008-02-07 有難嬉悲しメモ(2008/02/0)

2008-02-07 Perlでのオブジェクトとは? blessとは?

Perlでのオブジェクトとは、bless(祝福)されたリファレンスです。

では、blessとは、リファレンスとクラス名を結び付けることです。


以下にblessした場合と、しない場合のサンプルソースを例示します。

blessしない場合は、リファレンスとクラス名が結び付いていないので、メソッド起動でエラーとなっています。


プログラムソース(.\tstobject.pl)
#!/usr/bin/perl
use strict;
use DateString::DateStringx;
use DateString::DateStringy;

my $datex = DateString::DateStringx->new();
print $datex, "\n";   # blessされたリファレンスが格納されている
print $datex->to_string, "\n";

my $datey = DateString::DateStringy->new();
print $datey, "\n";   # 単なるリファレンスが格納されている
print $datey->to_string, "\n";

blessしたリファレンスを返すクラス(.\DateString\DateStringx.pm)
package DateString::DateStringx;
use strict;
sub new {
    my $class = shift; # 第一引数は、クラス名が渡される。
    my $time = shift || time();
    return bless { time => $time }, $class; # blessしたリファレンスを返す。
}
sub to_string {
    my $self = shift;
    return scalar localtime $self->{time};
}
1;
__END__

blessしないリファレンスを返すクラス(.\DateString\DateStringy.pm)
package DateString::DateStringy;
use strict;
sub new {
    my $class = shift; # 第一引数は、クラス名が渡される。
    my $time = shift || time();
    return { time => $time } # blessしていないリファレンスを返す。
}
sub to_string {
    my $self = shift;
    return scalar localtime $self->{time};
}
1;
__END__

実行結果
C:\Documents and Settings\xxx>perl .\tstobject.pl
DateString::DateStringx=HASH(0x1625e50)
Thu Feb  7 20:41:06 2008
HASH(0x1625f28)
Can't call method "to_string" on unblessed reference at .\tstobject.pl line 14.

2008-02-06 有難嬉悲しメモ(2008/02/06)

2008-02-06 クラスとオブジェクトのメソッド起動

以下は、クラスとオブジェクトでのメソッド起動のサンプルです。

また、クラス内やオブジェクト内で作成したオブジェクトのメソッドが、オブジェクトを返す時は、そのオブジェクトのメソッドを「->」で繋げることができます(03と04の例)。


プログラムソース(tstobject2.pl)
#!/usr/bin/perl
use strict;
use DateString::DateStringx;
my $yesterday = time() - 60 * 60 * 24;
my $date1 = DateString::DateStringx->new($yesterday);# クラスのインスタンス化
print "-------------------------------------------01\n";
print DateString::DateStringx->test2, "\n";       # クラスのメソッド起動
print "-------------------------------------------02\n";
print $date1->test2, "\n";                        # オブジェクトのメソッド起動
print "-------------------------------------------03\n";
print DateString::DateStringx->test3->test3, "\n";# クラス内で作成したオブジェクトのメソッド起動
print "-------------------------------------------04\n";
print $date1->test3->test3, "\n";                 # オブジェクト内で作成したオブジェクトのメソッド起動

DateStringx.pmモジュールソース(DateStringxクラス)
DateStringx.pm
package DateString::DateStringx;
use strict;
use DateString::DateStringz;

my $yesterday = time() - 60 * 60 * 24;
my $date1 = DateString::DateStringz->new($yesterday);

sub test3 {
    print "$_[0]---DateStringx---$_[1]", "\n";
    return $date1;
}

sub test2 {
    return "$_[0]---DateStringx---$_[1]";
}
sub new {
    my $class = shift;
    my $time = shift || time();
    return bless { time => $time }, $class;
}
sub to_string {
    my $self = shift;
    return scalar localtime $self->{time};
}
1;
__END__

DateStringz.pmモジュールソース(DateStringzクラス)
DateStringz.pm
package DateString::DateStringz;
use strict;
sub test3 {
    return "$_[0]---DateStringz---$_[1]";
}
sub new {
    my $class = shift;
    my $time = shift || time();
    return bless { time => $time }, $class;
}
sub to_string {
    my $self = shift;
    return scalar localtime $self->{time};
}
1;
__END__
実行結果(tstobject2.pl)
C:\xxx>tstobject2.pl
-------------------------------------------01
DateString::DateStringx---DateStringx---
-------------------------------------------02
DateString::DateStringx=HASH(0x285f18)---DateStringx---
-------------------------------------------03
DateString::DateStringx---DateStringx---
DateString::DateStringz=HASH(0x183048c)---DateStringz---
-------------------------------------------04
DateString::DateStringx=HASH(0x285f18)---DateStringx---
DateString::DateStringz=HASH(0x183048c)---DateStringz---

ちなみに、ここでは、クラスをインスタンス化したものをオブジェクトと書いてます。

クラスは、モジュールそのものです。

オブジェクトは、クラスのメソッド(コンストラクタ)がblessしたリファレンスを返したもの(インスタンス)。

2008-02-06 おすすめPerl本

新版Perl言語プログラミングレッスン入門編

新版Perl言語プログラミングレッスン入門編

CGI&Perlポケットリファレンス (Pocket reference)

CGI&Perlポケットリファレンス (Pocket reference)

Perlベストプラクティス

Perlベストプラクティス

2008-02-05 有難嬉悲しメモ(2008/02/05)

今日、「数学ガール」のコミック化の発表がありました。

たまたまだけど、この日に「数学ガール」の本にご縁になれて良かったです。

いつも、なかなかみつからない「数学ガール」本が、数学のコーナーに1冊あったんだよね!ラッキー!

2008-02-05 use宣言はrequire宣言プラスExporterモジュールのimport関数?

use宣言とは、実は、BEGINサブルーチン内でのrequire宣言とExporterモジュールのimportメソッド実行と、ほぼイコールなのです。

ほぼイコールと書いたのは、importメソッドがない場合は、呼び出しはスキップされ、また、importメソッドの自作が可能だからです。

しかし、普通、Exporterモジュールを継承してそのimportメソッドを使用します。

テストサンプルソース(testx.pl)
#use testx;
BEGIN { require testx; testx->import;} # use testx; と等価
#use testx qw($Y);
BEGIN { require testx; testx->import(qw($Y));} # use testx qw($Y);と等価
print "X=$X ", \$X, "\n";
print "Y=$Y\n";
print sum(5,3),"\n";
モジュールソース(testx.pm)
package testx;
#use Exporter;
#our @ISA    = qw(Exporter);
use base Exporter;          # use Exporter; our @ISA = qw(Exporter); と等価
our @EXPORT = qw($X &sum);
our @EXPORT_OK = qw($Y);
our $X = 10;
our $Y = 20;
sub sum {
 return $_[0]+$_[1]; # 渡された引数2つを加えて返す処理
}
print "in testx.pm : X=", \$X, "\n";
1;
処理結果
C:\Documents and Settings\xxx>perl testx.pl
in testx.pm : X=SCALAR(0x1ae706c)
X=10 SCALAR(0x1ae706c)
Y=20
8
補足1(Exporter、@ISA 、@EXPORT 、@EXPORT_OK)
Exporterの使用方法
package Module;

use Exporter;
@ISA = (Exporter);
@EXPORT = qw(sub1 sub2);

ここで登場した@ISAは、配列の各要素に、パッケージのベースクラスに当たるパッケージの名前を格納します。クラスは、@ISAにある順番でメソッドの検索を行います。

上記は、「use Exporter」で、Exporterモジュールを使用することを宣言し、@ISAにExporterを代入しています。次に@EXPOERTにインクルードさせたいサブルーチンを指定しています。ここではサブルーチンの sub1 と sub2 を自動的にインクルードするように指示しています。インクルード可能にしたサブルーチンは、インクルード先でパッケージ修飾を省略して sub1() のように宣言できます。

上記のモジュールを別のスクリプトから呼び出し、sub1 を実行するには次のようになります。

use Module;

sub1();

サブルーチン名を指定しない場合には、パッケージ内で定義されている全てのサブルーチンがインポート可能になります。

@EXPORT_OKを使用すると、@EXPORTのように定義したサブルーチンが呼び出し可能になりますが、呼び出し側で明示的に指定しなければなりません。

@EXPORT_OK
package Module;

use Exporter;
@ISA = (Exporter);

@EXPORT = qw(sub1 sub2);
@EXPORT_OK = qw(sub3);

sub sub1{ print "sub1\n"; }
sub sub2{ print "sub2\n"; }
sub sub3{ print "sub3\n"; }

sub1、sub2は「use モジュール名」で自動的にインポートされますが、 sub3はインポートされません。 sub3をインポートするには、「use モジュール名 qw(sub3)」のように明示的にインポートを指定します。

# 明示的に sub3 をインポートする。
# sub1、sub2 は自動的にインポートされます。
use Module qw(sub3); 

sub3();
http://www.rfs.jp/sb/perl/04/01.html#2.モジュール

補足2(BEGINサブルーチンについて)

BEGINサブルーチンは、スクリプトのコンパイル時に自動的に1回のみ呼び出されます。

http://d.hatena.ne.jp/chaichanPaPa/20071011/1192098600

2008-02-04 有難嬉悲しメモ(2008/02/04)

2008-02-04 use宣言とpackage宣言

use宣言

たとえば、以下のようにuse宣言をしたとします。

use Win32::OLE;

これは、WIN32フォルダにあるOLE.pmを使用することの宣言です。

つまり、WINDOWS上でのファイルのパス(拡張子を省略した場合はpmがデフォルト)のことなのです。

この場合は、まず、特殊配列 @INC に収められたパスを順番にチェックします。

@INCには、私の環境では「D:\Perl\lib」があり、libフォルダ配下にWin32フォルダがあります。

また、Win32フォルダ内には、OLE.pmがあり、上記宣言は、これを使用することができることの宣言なのです。


package宣言

たとえば、OLE.pm内に以下のようなパッケージ名のpackage宣言がしてあったとします。

package Win32::OLE;

これは、「Win32::OLE」で一つの名前空間となり、use宣言のWin32::OLEとは、全くの別物となります。まぎらわしい。

また、Perlでは、パッケージ名は、クラス名や名前空間名とエイリアスなので、以下のような感じでメソッドの起動ができます。

use Win32::OLE;
my $excel = Win32::OLE->new('Excel.Application', 'Quit');

この場合の「Win32::OLE」は、use宣言したものではなく、OLE.pm内でpackage宣言したものになります。


まとめ

use宣言は、単なるモジュールファイルへのファイルパスの指定。

package宣言は、単なるパッケージ名で、モジュールファイル名やそのファイルパスとは無関係。

しかし、モジュールファイル名とパッケージ名は、同じ名前になるケースが多い。


use宣言の「::」は、WINDOWS上では、「\」と同じ。

package宣言の「::」は、単なるパッケージ名の一部(たぶん)。

2008-02-03 有難嬉悲しメモ(2008/02/03)

2008-02-03 Perlでの「::」と「->」の違い

「::」は、モジュールのサブルーチンをコールするときに使います。

「->」は、モジュールのメソッドを起動するときに使います。(他にデリファレンスの時も使う)

違いは、メソッドでは、必ず、第一引数が自オブジェクトになるとこです。

つまり、メソッドでは、引数なしの時でも、自動的に第一引数が自オブジェクトになるのです。


テストソースtestx.pl
#!/usr/bin/perl
use strict;
use DateString;

my $date = DateString->new();

print DateString::to_string($date), "\n";  # サブルーチンコール(Sun Feb  3 12:08:37 2008が表示される)
print $date->to_string, "\n";              # メソッド起動(Sun Feb  3 12:08:37 2008が表示される)

print "\n-- オブジェクトのメソ\ッド起動 --\n";
print $date->test, "\n";
print $date->test(), "\n";
print $date->test("AAA"), "\n";
print "\n-- モジュールのサブルーチンコール --\n";
print DateString::test, "\n";
print DateString::test(), "\n";
print DateString::test($date), "\n";
print DateString::test("AAA"), "\n";
print "\n-- クラスのメソ\ッド起動 --\n";
print DateString->test, "\n";
print DateString->test(), "\n";
print DateString->test("AAA"), "\n";

DateString.pmモジュールソース
package DateString;
use strict;
sub test {
    print "$_[0]---test---$_[1]";
    return ();
}
sub new {
    my $class = shift;
    my $time = shift || time();
    return bless { time => $time }, $class;
}
sub to_string {
    my $self = shift;
    return scalar localtime $self->{time};
}
1;
__END__

処理結果
C:\Documents and Settings\xxx>perl testx.pl
Sun Feb  3 12:37:01 2008
Sun Feb  3 12:37:01 2008

-- オブジェクトのメソッド起動 --
DateString=HASH(0x1625e50)---test---
DateString=HASH(0x1625e50)---test---
DateString=HASH(0x1625e50)---test---AAA

-- モジュールのサブルーチンコール --
---test---
---test---
DateString=HASH(0x1625e50)---test---
AAA---test---

-- クラスのメソッド起動 --
DateString---test---
DateString---test---
DateString---test---AAA

ちなみに、bless関数は、第一引数のリファレンスを第二引数のクラス名と関連付け、そのリファレンスをオブジェクトとして返します。

2008-02-02 有難嬉悲しメモ(2008/02/02)

2008-02-02 Perlでの多次元配列の実体コピー

リファレンスのみをコピーする事をshallow copyと云い、実体までコピーする事をdeep copyと云います。

以下は、そのサンプルです。なにかの参考になれば、幸いです。


2次元deep copy
my $org_data_two_dimension = [["A01", "A02", "A03", "A04"],
                              ["B01", "B02", "B03", "B04"]];

        my $cpy_data_two_dimension = [map [@{$_}] , @$org_data_two_dimension];

        print $cpy_data_two_dimension->[0][0], "\n";
        print $cpy_data_two_dimension->[1][0], "\n";
        $cpy_data_two_dimension->[0][0] = "AAAAAAAAAAAA";
        $cpy_data_two_dimension->[1][0] = "BBBBBBBBBBBB";
        print $org_data_two_dimension->[0][0], "\n";
        print $org_data_two_dimension->[1][0], "\n";
        print $cpy_data_two_dimension->[0][0], "\n";
        print $cpy_data_two_dimension->[1][0], "\n";

3次元deep copy
my $org_data_three_dimension = [[["A01", "A02", "A03", "A04"],["C01", "C02", "C03", "C04"]],
                                [["B01", "B02", "B03", "B04"]]];
        
        my $cpy_data_three_dimension = [map [map [@{$_}], @{$_}] , @{$org_data_three_dimension}];

        print $cpy_data_three_dimension->[0][0][0], "\n";
        print $cpy_data_three_dimension->[1][0][0], "\n";
        $cpy_data_three_dimension->[0][0][0] = "AAAAAAAAAAAA";
        $cpy_data_three_dimension->[1][0][0] = "BBBBBBBBBBBB";
        print $org_data_three_dimension->[0][0][0], "\n";
        print $org_data_three_dimension->[1][0][0], "\n";
        print $cpy_data_three_dimension->[0][0][0], "\n";
        print $cpy_data_three_dimension->[1][0][0], "\n";
        print $cpy_data_three_dimension->[0][1][0], "\n";
        print $cpy_data_three_dimension->[0][1][1], "\n";

2008-02-01 有難嬉悲しメモ(2008/02/01)

良い本は、そのうち、本ブログにネタになります。たぶん。

2008-02-01 日付チェックルーチン for JavaScript

以下は、閏年も対応できるJavaScriptでの日付チェックルーチンです。

標準オブジェクトDateの以下の特性を利用して、入力日付をチェックしています。

Dateの引数に2008/2/30を与えると2008/3/1を返す。

<html>
<body>
<form name="FM">
<p><input type="text" name="text1"></p>
<p><input type="button" onClick="checktest()" value="test"></p>
</form>
<script type='text/javascript'>
function checktest() {
   alert(isDate(document.FM.text1.value));
}
function isDate(text) {
    if (text.length == 0 || text== "") {
        return false;
    }
    var arrDate = text.split("/");
    if(arrDate.length == 3) {    
        var date = new Date(arrDate[0] , arrDate[1] - 1 ,arrDate[2]);
        if(date.getFullYear() == arrDate[0] && 
          (date.getMonth() == arrDate[1] - 1) && 
           date.getDate() == arrDate[2]) {
            return true;
        }
    }
    return false;
}
</script>
</body>
</html>