2013-03-04

perl-5.005_04 が make できなくて困る

- 追記 make できました。-

perl-5.005 のテスト環境が欲しかったので、
WinXP に VMware Player と Ubuntu 12.04 をインストール。
perlbrew で perl-5.005_04 をインストールしてみたところ、見事にこける。

Linux とコンパイルに関して、ほとんどわからないので非常に困る。
インストールログのエラー部分はこんな感じ。

makedepend でエラーが出てるので makedepend.SH を修正。
$ diff -u makedepend.SH.orig makedepend.SH
--- makedepend.SH.orig 2004-01-14 05:16:31.000000000 +0900
+++ makedepend.SH 2013-03-03 00:00:00.000000000 +0900
@@ -51,6 +51,10 @@
  ;;
 esac
 
+# Avoid localized gcc/cc messages
+LC_ALL=C
+export LC_ALL
+
 # We need .. when we are in the x2p directory if we are using the
 # cppstdin wrapper script.
 # Put .. and . first so that we pick up the present cppstdin, not
@@ -113,7 +117,7 @@
     *.y) filebase=`basename $file .y` ;;
     esac
     case "$file" in
-    */*) finc="-I`echo $file | sed 's#/[^/]*$##`" ;;
+    */*) finc="-I`echo $file | sed 's#/[^/]*$##'`" ;;
     *)   finc= ;;
     esac
     $echo "Finding dependencies for $filebase$_o."
@@ -132,6 +136,7 @@
  -e '/^#.*<builtin>/d' \
  -e '/^#.*<built-in>/d' \
  -e '/^#.*<command line>/d' \
+ -e '/^#.*<command-line>/d' \
  -e '/^#.*"-"/d' \
  -e 's#\.[0-9][0-9]*\.c#'"$file.c#" \
  -e 's/^[  ]*#[  ]*line/#/' \


問題は次の miniperlmain.o のエラー。
'bool'型が定義されてないというのは何となくわかるが
ソースコードを修正するのか、
環境設定やコンパイルオプションを修正するのか判断がつかない。

エラーメッセージが日本語だとググれないので "$ LANG=C make" するとこんな感じ。

$ cd /home/user01/perl5/perlbrew/build/perl5.005_04
$ LANG=C make
`sh  cflags libperl.a miniperlmain.o`  miniperlmain.c
   CCCMD =  cc -DPERL_CORE -c -I/usr/local/include -O2   
In file included from perl.h:1276:0,
                 from miniperlmain.c:11:
cop.h:218:5: error: unknown type name 'bool'
cop.h:219:5: error: unknown type name 'bool'
....
"unknown type name bool" でググると perlbrew で fix された形跡を発見。
Fixes Configure options for ancient perls by friedo ・ Pull Request #249 ・ gugod/App-perlbrew ・ GitHub
perlbrew は 0.59 なので fix済みのようだけど、やっぱり make できない。

コンパイル環境がおかしいのかと、perl-5.8.9 を試してみたが、あっさりインストール完了。

考えられる状況としては
 ・コンパイルの設定が間違ってる
 ・コンパイラが非対応になった
 ・Ubuntu の環境が特殊
といったところか。

もうちょっと make 周りを理解しないと解決しなさそう。
とりあえず他のディストロでも試さないとダメかな。

- 追記 make できた! -

ついに解決!
何と15年前の ML に答えがありました。

[debian-users:05717] perl_5.004.04 & inn_1.7.2
[debian-users:05722] Re: perl_5.004.04 & inn_1.7.2
[debian-users:05745] Re: perl_5.004.04 & inn_1.7.2
ccflags='-Dbool=char -DHAS_BOOL'
このオプションを指定すればいいらしい。

Configure でうまく設定できなかったので config.sh を直接編集。
#config.sh
-    ccflags='-I/usr/local/include'
+    ccflags='-Dbool=char -DHAS_BOOL -I/usr/local/include'
make できたーーーーーーーーーーー!!!!

make test は2つほどこけます。
pragma/constant....FAILED at test 35
lib/db-btree.......Can't locate DB_File.pm in @INC (@INC contains: ../lib) at lib/db-btree.t line 21.
BEGIN failed--compilation aborted at lib/db-btree.t line 21.
FAILED at test 0
Failed 2 test scripts out of 190, 95.79% okay.
"で" な日々(2002年7月上旬)

perl 5.6.1 の compile で、make test の pragma/constant のところで
failed になってしまうのは、LANG を C にすると回避できた。
"$ LANG=C make test" で無事通過。
残りの DB_File.pm は BerkeleyDB 関連で、使わなければ無視してもいいみたい。

ということで "$ make install"。
$ perlbrew use 5.005_04
$ perl -v

This is perl, version 5.005_04 built for i686-linux

Copyright 1987-1999, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5.0 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using `man perl' or `perldoc perl'.  If you have access to the
Internet, point your browser at http://www.perl.com/, the Perl Home Page.

感動した(T T)
ここまでたどり着けたのも、ひとえに先人のお陰です。
ありがとう。


参考リンク

perlbrew - search.cpan.org

[Perl] Debian (lenny) Perl 5.005・5.6.2 インストール失敗 Kawanet Blog II/ウェブリブログ
Mac OS X 10.6(Snow Leopard)にPerl 5.005をインストールする:Kawanet Blog II
Ubuntu8.10にPerl5.005_04をインストール - なんとなく目記
LinuxにPerl5.005_04をインストールする方法(makeで失敗した場合の対処法) - DQNEO起業日記
Perl の make 時に miniperl でエラーになる場合の対処方法 :: drk7jp

[debian-users:05717] perl_5.004.04 & inn_1.7.2
[debian-users:05722] Re: perl_5.004.04 & inn_1.7.2
[debian-users:05745] Re: perl_5.004.04 & inn_1.7.2

2012-09-23

perl - windows の電源コントロール

コマンドプロンプトのみでサスペンド(スリープ)は、できないみたいなので perl で挑戦。

PowrProf.dll と shutdown.exe を呼んで
サスペンド、ハイバネート、シャットダウン、リブート、ログオフを
n 秒後に実行できるようにしてみました。

サスペンド後にタスクスケジューラでの復帰もできます。(後述)
テスト環境は winXP SP3、Activeperl 5.14。

#使用例

#t オプションのデフォルト値は 30秒
#カウントダウン中、CTRL+C で中止します

#60秒後にサスペンド
> pwrctrl.pl -s -t 60
> pwrctrl.pl --suspend --timeout 60

#即シャットダウン
> pwrctrl.pl -d -t 0
> pwrctrl.pl --shutdown --timeout 0

#ヘルプ
> pwrctrl.pl -?
> pwrctrl.pl --help

# pwrctrl.pl
# windows power control script

use strict;
use warnings;
use Getopt::Long;
use Win32::API;

our $VERSION = "0.02";

$| = 1;                 #no buffering
$Win32::API::DEBUG = 0; #Win32::API debug flag


my $cmd = init();

count_down($cmd);

my $return_code = $cmd->{'run'}->();

print "return code : $return_code\n";

exit;

#--------------------

sub init{
    usage() unless @ARGV;

    ###get options
    my $opts = {'timeout' => 30}; #default

    GetOptions($opts,
        'help|?',
        'hibernate|h',
        'suspend|s',
        'shutdown|d',
        'reboot',
        'logoff',
        'timeout=i',
        ) || usage();

    usage() if $opts->{'help'};


    ###set command
    my $api = Win32::API->new('Powrprof', 'SetSuspendState', 'NNN', 'N')
                || die "Can't load API : $!\n";

    my $cmd_table = {
        'hibernate'=> sub{ $api->Call(1,0,0)  },
        'suspend'  => sub{ $api->Call(0,0,0)  },
        'shutdown' => sub{ `shutdown -s -t 0` },
        'reboot'   => sub{ `shutdown -r -t 0` },
        'logoff'   => sub{ `shutdown -l -t 0` },
        };
    my $cmd = {'timeout' => $opts->{'timeout'}};

    for my $key (keys %$opts) {
        next if $key =~ /help|timeout/;
        $cmd->{'name'} = $key;
        $cmd->{'run'}  = $cmd_table->{$key};
        last;
    }

    usage(qq/option requires "-h -s -r -d -l -? [-t]"/)
        unless $cmd->{'name'};

    return $cmd;
}


sub count_down{
    my $cmd = shift;
    my $command = uc $cmd->{'name'};
    my $timeout = $cmd->{'timeout'};
    
    local $SIG{'INT'} = 'abort';

    print<<"EOM";

$command after $timeout seconds.
Press [CTRL+C] to abort.

EOM

    return if $timeout == 0;

    for my $sec (reverse (0..$timeout)) {
        printf "\r%3d sec", $sec;
        sleep 1;
        printf "\r%10s\r", "";
    }
}


sub abort {
    print "\n\n", "abort!\n";
    exit;
}


sub usage {
    my $msg = shift;
    print "$msg\n" if $msg;
    
    print<<"EOM";

- windows power control script v$VERSION -

Usage   : pwrctrl.pl option [timeout]
          pwrctrl.pl -d -t 60   # shutdown after 60sec

Options :
    -? --help         this document

    -h --hibernate    hibernate
    -s --suspend      suspend
    -r --reboot       reboot
    -d --shutdown     shutdown
    -l --logoff       logoff

    [-t] [--timeout]  run after n seconds
                      default is 30
EOM

    exit;
}

__END__


rundll32.exe だと自動復帰できない

> rundll32.exe PowrProf.dll,SetSuspendState 0,1,0

> rundll32.exe PowrProf.dll,SetSuspendState Sleep

コマンドプロンプトからサスペンドするのに上記のコードがWEB上で見つかります。
サスペンドするだけなら問題ないみたいですが、 タスクスケジューラでの自動復帰ができません。
※Windows7 だと問題なく自動復帰できるようです。


Rundll32.exe は正しい使用法なのか?

まず、Rundll32.exe の仕様を確認します。
Windows の Rundll と Rundll32 インターフェイス

これによると、Rundll32.exe は以下のように dll の関数呼び出しをする仕様です。
void CALLBACK
EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);

hwnd        - DLL で作成する任意のウィンドウのオーナー ウィンドウとして
              使用するウィンドウ ハンドル
hinst       - DLL のインスタンス ハンドル
lpszCmdLine - DLL で解析する ASCIIZ コマンド ライン
nCmdShow    - DLL のウィンドウを表示する方法を指定

Rundll32.exe は dll の関数への引数を 文字列 として渡します。
引数は dll がパースしてねという仕様です。


次に、SetSuspendState の仕様を確認します。
SetSuspendState function - MSDN
C++
BOOLEAN WINAPI SetSuspendState(
    _In_  BOOLEAN Hibernate,
    _In_  BOOLEAN ForceCritical,
    _In_  BOOLEAN DisableWakeEvent
);
SetSuspendState の正しい引数は bool値 3つ。

1つ目は、 0 = サスペンド、 1 = ハイバネート
2つ目は、 0 = アプリケーションの終了を待って中断、 1 = 強制的に中断
3つ目は、 0 = wake イベント有効、 1 = wake イベント無効


これらを踏まえると、先の Rundll32.exe 経由の SetSuspendState 呼び出しはこうなります。
> rundll32.exe PowrProf.dll,SetSuspendState 0,1,0

SetSuspendState( hwnd, hinst, "0,1,0", nCmdShow );

引数を渡すと DisableWakeEvent の値が TRUE になるので
wake イベントで復帰できないというわけです。


つまり、Rundll32.exe 経由での SetSuspendState 呼び出しは間違ってます。


perl 以外の方法

1. SetSuspendState というソフトを使う。
SetSuspendState - Vector
Sleep/Standby
> SetSuspendState
  or
> SetSuspendState 0

Hibernate
> SetSuspendState 1

非常に簡易なソフト。
サスペンドか、ハイバネートするだけ。
秒数の指定とかもできないけど、そのへんはバッチなりなんなりで対応。

ソースを見ると下のように ForceCritical の値が TRUE なので注意が必要かも。

SetSuspendState( 0, 1, 0 );  // Sleep
SetSuspendState( 1, 1, 0 );  // Hibernate


2. Ruby で SetSuspendState を実行。
コマンドラインからWindows PCを停止(スリープなど)する方法 | TipsZone


3. お好きな言語でAPIを叩く。


-------------------------
なんで shutdown.exe にサスペンド、ハイバネートのオプションないんでしょうね?


参考リンク

Windows の Rundll と Rundll32 インターフェイス
SetSuspendState function
SetSuspendState function (Windows)
Application.SetSuspendState メソッド (System.Windows.Forms)

プログラミングTips : SetSystemPowerState() の罠
コマンドラインからWindows PCを停止(スリープなど)する方法 | TipsZone
SetSuspendState - Vector

2012-08-04

いまさら perl v5.5

もっぱら perl はローカルで使ってるので、バージョンやモジュールで困ることはないのですが、
久しぶりにプロバイダの提供スペースで CGI 使って遊ぼうと思い環境調査してみました。

#!/usr/local/bin/perl

use strict;
use warnings;

print "Content-type: text/html;\n\n";

print "perl : $]<br>\n";
print "$_ : $ENV{$_}<br>\n" for sort keys %ENV;

なぜか500エラー。
shebang は合ってるしなんで?
試しに use を外してみたら動きました。

古いといっても v5.8 だろうと思っていたところ
驚愕の v5.5.3 !!!!!

ちょっと手元の corelist さんに聞いてみましょう。
corelist は v5.8.9 以降なら標準で入ってるみたいです。

C:\>corelist Module::CoreList
Module::CoreList was first released with perl v5.8.9

C:\>corelist strict
strict was first released with perl 5

C:\>corelist warnings
warnings was first released with perl v5.6.0

C:\>corelist utf8
utf8 was first released with perl v5.6.0

C:\>corelist Encode
Encode was first released with perl v5.7.3

・・・。
strict しか使えないじゃないですか!!
いまさら EUC でコーディングとかしたくないなー。
正直、サーバーのエラーログをエラーまみれにしそうな予感しかしない。


perl v5.5.3 で使えないもの

・warnings.pm
・utf8.pm
・Encode.pm

# 3引数 open は perl v5.6 以降
open( INFO, ">", $datafile ) or die $!;

# 間接ファイルハンドルも perl v5.6 以降
open( my $in, "> $infile" )  or die $!;

# our も perl v5.6 以降
our $var;
# 代わりに use vars
use vars qw($var);
# perl v5.14 から一部の関数がリファレンスを受け取れるようになったので
# この書き方で楽してるとデリファレンスでエラーが出てハマルかも。

http://perldoc.perl.org/perl5140delta.html#Syntactical-Enhancements

|----------------------------+---------------------------|
| Traditional syntax         | Terse syntax              |
|----------------------------+---------------------------|
| push    @$arrayref, @stuff | push    $arrayref, @stuff |
| unshift @$arrayref, @stuff | unshift $arrayref, @stuff |
| pop     @$arrayref         | pop     $arrayref         |
| shift   @$arrayref         | shift   $arrayref         |
| splice  @$arrayref, 0, 2   | splice  $arrayref, 0, 2   |
| keys    %$hashref          | keys    $hashref          |
| keys    @$arrayref         | keys    $arrayref         |
| values  %$hashref          | values  $hashref          |
| values  @$arrayref         | values  $arrayref         |
| ($k,$v) = each %$hashref   | ($k,$v) = each $hashref   |
| ($k,$v) = each @$arrayref  | ($k,$v) = each $arrayref  |
|----------------------------+---------------------------|

まだまだハマリどころがありそう。
文字コード周りは Jcode.pm を使うのかな。


500 Internal Server Error の対応

500エラーが出たときにサーバーのエラーログが見れない場合どうするか。
CGI::Carp を使う。

C:\>corelist CGI::Carp
CGI::Carp was first released with perl 5.004
perl v5.4 からコアモジュールで安心。
# エラーをブラウザに表示
use CGI::Carp qw(fatalsToBrowser);

# エラーをログファイルに書き出す
BEGIN {
  use CGI::Carp qw(carpout);
  # perl v5.5.3 なので 3引数open は使えない
  open(LOG, ">> ./err.log") or die $!;
  carpout(LOG);
}

fatalsToBrowser はメジャーだけど
carpout は今回調べるまで知らなかった。

他にも KCatch.pm というモジュールもあります。


perl v5.5.3 環境を作る?

perl のバージョンを切り替える perlbrew というものがありますが、Windows だと使えないっぽい。

Strawberry Perl も ActivePerl も v5.5.3 のバイナリなんて置いてないしなー。
などとググってるうちに発見した Vector の Perl for Win32(perl5) は v5.5.7 らしい。
置いてあるディレクトリが win95 !!
これを入れる勇気はちょっとないなと。

いっそのこと、サーバー借りちゃった方が楽かもね。


参考リンク

History / Changes - perldoc.perl.org
コアドキュメント - perldoc.jp
Perl Hackers Hub:第14回 最新Perl使いこなし術―リファレンスの引き方,5.10以降の新機能(2)
Perl Hackers Hub:第14回 最新Perl使いこなし術―リファレンスの引き方,5.10以降の新機能(3)
perl5.10から5.16の新機能まとめ

CGI::Carp - search.cpan.org
[Perl] KCatch.pm/CGI エラーメッセージをブラウザに表示
Jcode - search.cpan.org

perlbrew - search.cpan.org

Windows で複数の perl を使い分けよう! - JPerl Advent Calendar 2010 Win32 Track
Strawberry Perl for Windows
ActivePerl

2012-06-14

Firefoxの検索クエリ変更

Firefox13 がリリースされたので入れてみました。
Firefox7 以降入れてなかったんですが、起動も速いし動作も速い。
いつの間にやらディスクキャッシュからメモリキャッシュになったんですね。

Sleipnir のキャッシュをRAMディスクにして使用してますが
それよりも若干早い感じがします。

Firefox はカスタマイズするのにアドオン探さなきゃいけないのが面倒なので
いまいち移行しきれないのですが、1つ障害が解決したのでメモ。

長年、検索窓のクエリ変更がうまくいかなかった謎が解決。
searchplugin を変更後に Profile 内の search.json を削除。
これで変更が反映されます。

次は google 検索を変更。
インスタント検索が始まってから、検索クエリに num=50 を足しても
表示件数が変更できなかったのですが、以下の手順で変更できます。


Firefoxが起動してない状態で
・Mozilla Firefox/searchplugins/google-jp.xml を変更
<Url type="text/html" method="GET" template="http://www.google.co.jp/search">
  <Param name="q" value="{searchTerms}"/>
  <Param name="complete" value="0"/> <!--インスタント検索オフ-->
  <Param name="as_qdr" value="all"/> <!--期間-->
  <Param name="num" value="50"/> <!--表示件数-->
  <Param name="gbv" value="1"/>
</Url>
・Profile内の search.json を削除


Sleipnir だと
http://www.google.co.jp/search?q={all}&num=50
だけで50件表示できるんですけど何でですかね?

2012-05-04

perl - Markdown変換スクリプト

ネタを整理するのに Markdown で書くと便利なのかなと調べていると
CPAN に Text::Markdown というモジュールがあったので
思いつきで変換スクリプト書いてみました。

スクリプトにファイル名を渡すか、__END__ 以下に Markdown を書いて使います。
出力を保存する場合はリダイレクトして下さい。

# markdown2html.pl

use strict;
use warnings;

use Text::Markdown 'markdown';

my $file = shift;
my $text = "";

if ($file) {
 open(my $fh, '<', $file) or die($!);
  local $/;
  $text = <$fh>;
 close $fh;
} else {
 local $/;
 $text = <DATA>;
}
my $html = markdown($text);

#print $text;
print $html;


__END__
#markdown sample
##h2
###h3

paragraph  
hoge
moge

[リンク文字列](http://example.com/)
[リンク文字列](http://example.com/ "タイトル")
<http://example.com>

![画像の説明](/path/to/image.jpg "タイトル")

- listA
- listB
- listC

---

1. listA
2. listB
3. listC

>blockquote
blockquote

    ...code...
`...code...`
ドラッグアンドドロップ用にバッチファイルも付けておきますね。
スクリプトと保存先のパスは適宜修正して下さい。
::markdown2html.bat

set markdown2html="C:\markdown2html.pl"
set output="C:\%~n1%.htm"

perl %markdown2html% %1 > %output%

pause

Markdown用のエディタとかもあるので、わざわざこんなの使うことないですよね。
個人的には秀丸から perl に渡して処理とかよくやるので、使うかなと思いまして。

参考リンク

Tomas Doran / Text-Markdown - search.cpan.org
Daring Fireball: Markdown
blog::2310 » Markdown文法の全訳
Markdown - Wikipedia

2012-05-02

rtmpdump - v2.5 Unofficial binaries

RTMPDump v2.5 GIT-2012-03-31 (Handshake 10 support by Xeebo)
http://stream-recorder.com/forum/showpost.php?p=44648&postcount=96

--swfVfy | -W オプションは Type2 未対応らしくこんなエラーが出ます。
ERROR: HandleCtrl: SWFVerification Type 2 request not supported,
       attempting to use SWFVerification Type 1! Patches welcome...

Perl - リンク集

Perl

The Perl Programming Language
本家
The Comprehensive Perl Archive Network
CPAN
The CPAN Search Site - search.cpan.org
ActivePerl
Windows(32|64bit), MacOS, Linux(32|64bit)
Strawberry Perl
Windows(32|64bit)

Document

Perl programming documentation
perldoc
perldoc.jp
perldoc邦訳
Argrath's lair
pod日本語訳仮置き場
ちょいマシなCPAN機械翻訳

Framework | Library

Perlbrew
ユーザー環境下で複数バージョンの perl を管理
App-perlbrew - search.cpan.org
Catalyst
The Elegant MVC Web Application Framework
Catalyst - search.cpan.org
Moose
A postmodern object system for Perl 5
Moose - search.cpan.org
Moose 邦訳ドキュメント - perldoc.jp
PSGI/Plack
Perl Superglue for Web frameworks and Web Servers (PSGI toolkit)
Plack - search.cpan.org
Mojolicious
Real-time web framework
Mojolicious - search.cpan.org
Mojolicious リファレンス - サンプルコードによるPerl入門
ImageMagick
画像処理ライブラリ
PerlMagick, Perl API for ImageMagick
Image::Magick - search.cpan.org
ChartDirector for Perl
チャート描画ライブラリ
EPIC
Eclipse用 Perl IDE

News

Perl.com
O'Reillyのperlニュースサイト

Community

Perl Mongers
YAPC - Yet Another Perl Conference
Perl-users.jp - 日本のPerlユーザのためのハブサイト
PerlMonks

Learn

--- 基礎 ---
サンプルコードによるPerl入門
Perl基礎文法最速マスター - サンプルコードによるPerl入門
Perlオブジェクト基礎文法最速マスター - 燈明日記
Perl5編 - Programing Place
--- 基礎以上 ---
Perl-users.jp
JPerl Advent Calendar
JPerl Advent Calendar 2008
JPerl Advent Calendar 2009
JPerl Advent Calendar 2010
JPerl Advent Calendar 2011
JPerl Advent Calendar 2012
連載:モダンPerlの世界へようこそ|gihyo.jp
連載:Perl Hackers Hub|gihyo.jp
特集:Happy Testing Perl|gihyo.jp
--- 日本語処理 ---
Encode.pm - search.cpan.org
404 Blog Not Found:perl - Encode 入門
404 Blog Not Found:perl - Encode 中級
404 Blog Not Found:perl - use encoding; #は黒歴史
404 Blog Not Found:perl - EncodeでXSSを防ぐ
404 Blog Not Found:perl - use CGI; use Encode; # 非英語Webプログラミング3原則
404 Blog Not Found:perl - 最速のUTF-8処理法
Encodeでラクラク日本語処理 - JPerl Advent Calendar 2009
続・Encodeでラクラク日本語処理 - JPerl Advent Calendar 2010 Casual Track
モダンPerlの世界へようこそ:第32回 Encode:日本語だけ扱えればよいのではなく|gihyo.jp
--- その他 ---
Perl道場
PerlエンジニアがつくるPerlエンジニアのための検定試験

Books

--- O'Reilly's CD bookshelf ---
[eng]Perl in a Nutshell 第2版 - 2002
[eng]Learning Perl 第3版 - 2001
[eng]Learning Perl Objects, References and Modules - 2003
[eng]Programming Perl 第3版 - 2000
[eng]Advanced Perl Programming - 1997
[eng]Perl Cookbook - 1998
日本語インデックス
[eng]Perl Cookbook 第2版 - 2003
[eng]Mastering Regular Expressions 第2版 - 2002
[eng]Perl & LWP - 2002
[eng]CGI Programming with Perl 第2版 - 2000
[eng]Perl & XML - 2002
[eng]Mastering Perl/Tk - 2002
[eng]Learning Perl on Win32 Systems - 1997
[eng]Perl for System Administration - 2000
--- Google Books ---
Google Books Downloader for Windows and Mac OS X
 
[eng]Learning Perl 第6版 - 2011
初めてのPerl 第3版 - 2003
[eng]Intermediate Perl 第2版 - 2012
続初めてのPerl 改訂版 - 2006
[eng]Mastering Perl - 2007
[eng]Learning Perl Objects, References, and Modules - 2003
[eng]Programming Perl 第4版 - 2012
プログラミングPerl VOLUME 1 第3版 - 2002
プログラミングPerl VOLUME 2 第3版 - 2002
Perlクックブック VOLUME 1 第2版 - 2004
Perlクックブック VOLUME 2 第2版 - 2004
実用Perlプログラミング 第2版 - 2006
ミニマルPerl: Unix/LinuxユーザのためのPerl習得法 - 2008
Perlベストプラクティス - 2006
詳説正規表現 第2版 - 2003
正規表現デスクトップリファレンス - 2004
[eng]Regular Expressions Cookbook - 2009
[eng]Perl Debugger Pocket Reference - 2004
[eng]Perl & Lwp - 2002
[eng]Spidering Hacks: 100 Industrial-Strength Tips & Tools - 2003
CGIプログラミング 第2版 - 2001
入門Perl DBI - 2001
初めてのPerl Win32システム -1998
Perl & XML -2002
[eng]Perl Graphics Programming - 2002
Perl/GNUソフトウェアによるWebグラフィックスプログラミング - 2000
[eng]Web Security Testing Cookbook - 2008
[eng]Perl Hacks: Tips & Tools for Programming, Debugging, and Surviving - 2006
モダンPerl入門: 実務で使う実用的なPerlの"すべて" - 2009
PerlフレームワークCatalyst完全入門 - 2010

2012-04-29

オブジェクト指向とイデア論

HTML→CSS→JavaScript(挫折)→CGI(Perl)→PHP,VB ... と、
元はホームページ作りたかったので、そこから色々つまみ食いしては忘れ、
忘れた頃になにかプログラム組みたくなったりして現在に至るわけですが、
とりわけJavaScriptには苦い思い出があります。

当時はIE6、ネットスケープとかだったのでステータスバーに文字を流すとかやってた牧歌的な時代です。
JavaScript本を一冊買ったもののメソッドだのプロパティだの意味が分からない。
今にして思えば、JavaScript自体のオブジェクト、ブラウザのオブジェクト、 DOM なんかがごっちゃになってたんだなと。

全体は見通せないし、デバッグの仕方も分からないし、労力の割りに大したこと出来なくて投げたわけです。
ここでオブジェクト指向的なものに苦手意識が植え付けられます。

その後、CGI(Perl)を改造したりしてるとモジュールに出会う。
モジュールはオブジェクト指向で書かれてるらしいので苦手意識がありつつも調べてみる。
やっぱりここでも挫折するわけですが、すごく印象に残っているのがこの記事。

@IT:オブジェクト指向の世界(10) プラトン編-イデア論とクラス/インスタンス

読んだ当時はさっぱりでしたが、オブジェクト指向って哲学由来なんだなと。

そこで自分のプログラミングの入り口たる HTML と CSS に戻りますが、
文章と装飾の分離という考え方は 「本質」 と 「本質でないもの」 の分離で
哲学っぽいなと思っていたので、非常に印象深いわけです。


プラトンのイデア論

プラトンは「無知の知」で知られるソクラテスの弟子。
ソクラテスは倫理を追求した人なので、プラトンもかなりその影響を受けてます。
そのせいなのかプラトンは理想主義的な印象。

イデア論とは、端的に言えばこういうことです。
ものには イデア(idea) という真の原型が存在する。
この世にあるものは イデア のコピーに過ぎない。

この考え方がオブジェクト指向に似てるわけです。

イデア - クラス
イデアのコピー - インスタンス(オブジェクト)

似てるというよりそのまんまですね。


抽象と具体

一度クラスを使ったプログラムを作ってみれば、その後は理解が進むものです。
一方で、humanクラスからbaker、animalクラスからdogを作るみたいな例は なんで分かりづらいのか。

それは、クラスが抽象化されたものだから、じゃないかと。

抽象化というのは、対象の特徴、要素を抜き出すことです。
抽象化されたクラスを説明するのにクラスから入ると、 具体的なもの(オブジェクト)がイメージしにくい。

むしろ、複数のオブジェクトからクラスを作った方が、 抽象化のプロセスから考えても分かりやすいのでは。


プラトンの弟子のアリストテレスもイデア論はしっくりこなかったようです。
「実体が先にあって、それらを基にして人間が頭の中で抽象化して創りだしたものを
イデアと呼んでいるにすぎないというのが自然な考え方である」
アリストテレスは帰納的アプローチが好きなので
実体がなく検証しようがないイデアという概念は納得いかないのでしょう。

アリストテレスも、オブジェクトからクラスの方が分かりやすいタイプだと思いませんか。


PCは叡智の結晶

ハイテクの塊であるPCに古代ギリシャの哲学が生きている。
それだけ過去の賢人は普遍的なもの、本質に迫っていたんだなと感じます。

PCを通じて人類の叡智に触れられるなんて、PCはオモチャとして最高。
いろんな概念に触れられるオモチャなんて他にはそうないんじゃないでしょうか。


参考リンク

@IT連載 「オブジェクト指向の世界」
オブジェクト指向と哲学
ギリシア哲学への招待状

2012-04-28

可能性と蓋然性の違い

普段、なにげなく使ってる「可能性」という言葉。

「可能性が高い(低い)」 というのは間違っていて、
「蓋然性が高い(低い)」 と使うのが正しいとのこと。

可能性 は possibility、起こるか起こらないか、有るか無いか。
蓋然性 は probability、確からしさの度合い、確率。
「可能性がある(ない)」
「蓋然性が高い(低い)」
これが本来の使い方らしい。

そうはいっても普通は「蓋然性」っていっても通じないよね。
日銀のレポートぐらいでしか見たことないし。

英語に訳す場面だと使い分けないとまずいのでしょう。

日本語だと曖昧だけど、英語にすると明確に違う実感が湧くのは何ででしょうね?
プログラミングもいくつか違う言語をつまみ食いすると理解が進んだりしますし。
もしや、これは単に習熟度が低い(日本語含む)ということか!

概念と言語というテーマは面白いですね。
この面白さに中学の時、気付いていればなー。

2012-04-08

Bloggerのテンプレートをいじる

というエントリーを書きたかったがまたもや挫折・・・。
Blogger を始めたときも挫折して CSS をいじったぐらいで現在に至るわけです。
なんというかドキュメントがしょぼいんですよね。

さらに今はテンプレートが version2 になってますが、このドキュメントも見当たらない。
とりあえず分かったところまでまとめます。


コード

Blogger のテンプレートは XHTML にコードを埋め込む形式。
Movable Type の MTML に書き方が似てますね。
簡略化したテンプレートの一部はこんな感じ。
<div id='header-wrapper'>
 <b:section class='header' id='header'>
  <b:widget type='Header' id='Header1' expr:title='data:blog.title'>

   <b:includable id='main'>
    <h1 class='title'>
     <data:title/>
    </h1>
   </b:includable>

  </b:widget>
 </b:section>
</div>


<b:section>

テンプレートはいくつかの <b:section> を持ちます。

<b:section> の中に <b:section> は入れ子にできません。
<b:section> は <b:widget> しか持てません。
<b:section> は複数の <b:widget> を持てます。

<b:section> は <div> に置換されます。

属性 任意性 備考
id string 必須 一意の名前。
class string オプション よく使用されるクラス名は navbar, header, main, sidebar, footer など。
maxwidgets number オプション この section で使用できる widget の最大数。
指定しない場合、上限なし。
showaddelement 'yes' | 'no' オプション レイアウトページで [ガジェットを追加] リンクを表示するかどうか。
growth 'horizontal' | 'vertical' オプション この section 内の widget の並べ方。水平か垂直。


<b:widget>

<b:widget> は <b:includable> しか持てません。
<b:widget> には id='main' を指定した <b:includable> が1つ必要です。

<b:widget> は <div> に置換されます。

属性 任意性 備考
id string 必須 テンプレート内の widget の id は一意である必要があります。
widget の id は変更できません。
変更する場合は、一度 widget を削除して、新しく作成します。
type string 必須 widget の種類。
BlogArchive、Blog、Feed、Header、HTML、SingleImage、LinkList、 List、Logo、BlogProfile、Navbar、VideoBar、NewsBar など。
locked 'yes' | 'no' オプション ロックされた widget はレイアウトページで移動、削除できません。
title string オプション レイアウトページでの widget の表示タイトル。
指定しない場合、'List1' などのデフォルトのタイトルが使用されます。
pageType 'all' | 'main' | 'item'| 'archive' オプション 指定した表示タイプにのみ表示されます。
mobile 'default' | 'yes' | 'no' | 'only' オプション widget をモバイルで表示するかどうかを指定します。
default を指定すると、モバイルでは Header、Blog、Profile、PageList、AdSense、Attribution が表示されます。


<b:includable> <b:include>

<b:includable id='main'> はデフォルトで展開されます。

その他の id 属性が指定された <b:includable id ='***'> は関数みたいなもので
<b:include name='***'> を使って呼び出して使います。

要は <b:includable> の中にいろいろとコードを書いていくわけです。

includable
属性 任意性 備考
id string 必須 一意の名前。
var string オプション include から渡される引数を受け取る変数名。
include
属性 任意性 備考
name string 必須 一意の名前。
data string オプション includable に渡す何らかのデータ構造。
(ex. blog, blog.title, posts, feedData ...)

<b:include> を使うとこんな感じになります。
<div id='header-wrapper'>
 <b:section class='header' id='header'>
  <b:widget type='Header' id='Header1' expr:title='data:blog.title'>

   <b:includable id='main'>
    <h1 class='title'>
     <b:include name='title'/>
    </h1>
   </b:includable>

   <b:includable id='title'>
    <b:if cond='data:blog.url == data:blog.homepageUrl'>
     <data:title/>
    <b:else/>
     <a expr:href='data:blog.homepageUrl'><data:title/></a>
    </b:if>
   </b:includable>

  </b:widget>
 </b:section>
</div>
<b:include name='title'/>

<b:includable id='title'>
  ...
</b:includable>
を呼んでるのが分かるでしょうか。
前はこの <b:includable> が分からなくて挫折しました。

また、 <b:includable> は次のようにして引数を受け取ることも出来ます。
<b:includable id='main'>
 <b:include name='post' data='blog'/>
</b:includable>

<b:includable id='post' var='arg'>
 <data:arg.title/><br/>
</b:includable>


<data:***/>

<data:***/> タグはブログの各データを展開するだけなので、これは簡単ですね。
<data:blog.title/>
<data:blog.url/>
XHTML タグの中では書き方が違うので注意が必要です。
この書き方はダメです。
<a href='<data:blog.homepageUrl>'> TITLE </a>
XHTML タグの属性の前に expr: を付けて data:*** とします。
なぜか expr: はドキュメントに載ってません。
<a expr:href='data:blog.homepageUrl'> TITLE </a>

グローバルに参照できるデータ
<data:blog.title/> のように参照します。

この他にもブログのソースの一番下の方の
_WidgetManager._SetDataContext() 内に
参照できるデータが JavaScript のオブジェクト形式で書いてあります。

blog
属性 備考
title string ブログのタイトル。
homepageUrl string ブログの URL。
http://*****.blogspot.jp/
canonicalHomepageUrl string ブログの URL。
http://*****.blogspot.com/
pageType 'index' | 'item' | 'archive' | 'static_page' 現在のページの種類。
pageTitle string 現在のページのタイトル。
url string 現在のページの URL。
http://*****.blogspot.jp/*****
canonicalUrl string 現在のページの URL。
http://*****.blogspot.com/*****
encoding string ブログで使用する文字エンコード。
isMobile bool モバイルかどうか。
feedLinks string フィードの<link>タグ(XHTML)。

各 widget 内で参照できるデータ
widget の type や属性は追加、統廃合されてるようなので
ここに載ってなかったり、使えなかったりするかもしれません。

Header
属性 備考
title string ブログのタイトル。
description string ブログの説明。
mobile bool モバイルかどうか。
useImage bool ヘッダーに背景画像を使うかどうか。
imagePlacement 'BEHIND' |
'REPLACE' |
'BEFORE_DESCRIPTION'
背景画像の位置。
sourceUrl string 背景画像の URL。
backgroundPositionStyleStr string 背景画像の backgroundPosition。
widthStyleStr string 背景画像の幅。
height string 背景画像の高さ。
width string 背景画像の幅。

Blog
属性 備考
olderPageTitle string 過去の投稿ページへのリンクのタイトル。
olderPageUrl string 過去の投稿がある場合、その投稿の URL。
newerPageTitle string 新しい投稿ページへのリンクのタイトル。
newerPageUrl string 新しい投稿がある場合、その投稿の URL。
     
commentLabel string コメント数を表示するために使用するフレーズ (例"コメント数")。
authorLabel string 投稿者が誰かを示すために使用するフレーズ (例"投稿者")。
timestampLabel string 投稿時間を示すために使用するフレーズ (例"に投稿")。
postLabelsLabel string 投稿のラベルのリストを示すフレーズ (例"この投稿のラベル")。
backlinksLabel string 投稿のバックリンクを示すフレーズ (例"この投稿へのリンク")。
numPosts string 投稿数。
shareMsg string
homeMsg string homepage リンクのテキスト。
mobile bool モバイルかどうか。
desktopLinkUrl string desktopLink の URL。モバイル用?
desktopLinkMsg string desktopLink のテキスト。モバイル用?
mobileLinkUrl string mobileLink の URL。モバイル用?
mobileLinkMsg string mobileLink のテキスト。モバイル用?
     
defaultAdStart string Google AdSense
defaultAdEnd string Google AdSense
adCode string Google AdSense
adStart string Google AdSense
adEnd string Google AdSense
     
feedLinks list 現在のページのフィードのリスト。
- url string フィードの URL。
- name string フィードの名前 (例'投稿' や 'コメント' など)。
- feedType 'Atom' | 'RSS' フィードの種類。
- mimeType string フィードの MIME 形式。
     
posts list 現在のページのすべての投稿のリスト。
- dateHeader string この投稿の日付。この投稿がリストにおいてその日最初の投稿であった場合にのみ表示します。
- timestamp string この投稿のタイムスタンプ。 dateHeader とは異なり、これはすべての投稿に存在します。
- timestampISO8601 string この投稿の ISO8601 形式のタイムスタンプ。
- id string この投稿の ID 番号。
- url string この投稿の Permalink。
- link string この投稿の link。
- title string この投稿のタイトル。
- body string この投稿のコンテンツ。
- author string 投稿者のハンドル ネーム。
- authorProfileUrl string 投稿者プロフィールへの URL。
- thumbnailUrl string この投稿の画像のサムネイルの URL。
- snippet string この投稿のコンテンツの出だし部分。
- isDateStart bool その日最初かどうか。
- isFirstPost bool その日最初の投稿かどうか。
- hasJumpLink bool JumpLink (もっと読む)があるかどうか。
- jumpText string JumpLink のテキスト(例"もっと読む")。
- allowComments bool この投稿がコメントを許可している場合は 'True'。
- numComments string この投稿のコメント数。
- showThreadedComments bool スレッド式のコメントを表示するかどうか。
- showBacklinks bool この投稿のバックリンクを表示するかどうか。
- numBacklinks string この投稿のバックリンク数。
- addCommentUrl string この投稿の [コメントを追加] フォームの URL。
- addCommentOnclick string [コメントを追加] クリック時の JavaScript code。
- emailPostUrl string この投稿の [この投稿をメール送信] フォームの URL。
- editUrl string この投稿の [編集] フォームの URL。
- dummyTag string ダミータグ。
     
- labels list この投稿のラベルのリスト。
-- name string ラベルのテキスト。
-- url string このラベルが付いた投稿リストページの URL。
-- isLast bool このラベルがリストの最後かどうか (カンマを付けるのに役立ちます)。
     
- feedLinks list この投稿に特有のフィードのリスト (ブログ全体の feedLinks とは異なり、投稿のコメント用のフィードなどを含めることができます)。それぞれに次のものが含まれます。
-- url string フィードの URL。
-- name string フィードの名前 (例'投稿' や 'コメント')。
-- feedType 'Atom' | 'RSS' フィードの種類。
-- mimeType string フィードの MIME 形式。
     
- comments list この投稿のすべてのコメントのリスト (アイテム ページ上のみ)。
-- id string コメントの ID 番号。
-- body string コメントの本文。
-- timestamp string コメントが作成された時刻。
-- author string コメントの投稿者のハンドル ネーム、または '匿名'。
-- authorUrl string コメントが匿名でない場合、コメントの投稿者のプロフィールの URL。
-- deleteUrl string このコメントを削除するための URL。
-- isDeleted bool このコメントを削除するかどうかを指定します (削除されたコメントは、プレースホルダーに置き換えられます)。

BlogArchive
属性 備考
title string ウィジットのタイトル。
style 'MENU' | 'FLAT' | 'HIERARCHY' 表示形式。
     
data list アーカイブ ユニットのリスト。
- name string このアーカイブの期間の名前 (ex. "2006年8月")。
- url string この期間の投稿を含むページのリンク。
- post-count string この期間中の投稿数。

Feed
属性 備考
title string ウィジットのタイトル。
feedUrl string フィードの URL。
     
feedData list フィードのアイテムです。
- title string アイテムのタイトル
- str_published string アイテムが公開された時期
- published string アイテムが公開された時期 (秒単位)。
- str_updated string アイテムの最終更新日
- updated string アイテムの最終更新日 (秒単位)。
- author string アイテムの著者。
- summary string 可能な場合はアイテムの抜粋。
     
- alternate list このアイテムに関する詳細情報の提供元。
-- href string このアイテムの Permalink。
-- type string このアイテムのコンテンツ タイプ。

テキスト / HTML / JavaScript
属性 備考
title string ウィジットのタイトル。
content string ウィジットのコンテンツ。

Image
属性 備考
title string ウィジットのタイトル。
sourceUrl string 画像の URL。
width string 画像の幅、ピクセル単位。
height string 画像の高さ、ピクセル単位。
caption string 画像のキャプション。

LinkList
属性 備考
title string ウィジットのタイトル。
links list リンクのリスト。
- name string リンクのテキスト。
- target string リンクの URL。

List
属性 備考
title string ウィジットのタイトル。
items list アイテムのリスト。

Logo
属性 備考
fullButton string 選択した Blogger ボタンの URL。

Profile
属性 備考
title string ウィジットのタイトル。
userUrl string 投稿者のプロフィールの URL。
location string 投稿者のプロフィールの場所。
aboutme string プロフィールの "自己紹介" 情報。
displayname string 投稿者のハンドル ネーム。
     
photo list ユーザーのプロフィールの写真。
- url string 写真の URL。
- width string 写真の幅、ピクセル単位。
- eight string 写真の高さ、ピクセル単位。
- alt string 写真の "alt" テキスト。

Label
属性 備考
title string ウィジットのタイトル。
display 'list' | 'cloud' 表示形式。
     
labels list ラベルのリスト。
- name string ラベルのテキスト。
- count string このラベルが付いている投稿数。
- url string このラベルが付いている投稿を表示しているページへのリンク。
- cssSize string クラウド形式の文字のサイズ。

Gadget
属性 備考
title string ウィジットのタイトル。
gadgetSnippet
renderingUrl
nonSocialFragment
errorMessage

<data:***/> タグの詳細はドキュメントを参照してください。
レイアウト データ タグ - Blogger ヘルプ


<b:if> <b:else/>

if 文は特に説明はいらないでしょう。
else はありますが、else if はありません。
<b:if cond='条件式'>
 ...
</b:if>

<b:if cond='条件式'>
 ...
<b:else/>
 ...
</b:if>
<b:if cond='data:blog.url == data:blog.homepageUrl'>
 <data:title/>
<b:else/>
 <a expr:href='data:blog.homepageUrl'><data:title/></a>
</b:if>
現在の投稿がバックリンクを表示するように設定されている場合は true。
<b:if cond='data:post.showBacklinks'>

現在のページがアイテム ページ (投稿ページ) であるなら true。
<b:if cond='data:blog.pageType == "item"'>

ハンドル ネームが Fred でなければ true。
<b:if cond='data:displayname != "Fred"'>

現在の投稿に複数のコメントがあれば true。
<b:if cond='data:post.numComments > 1'>


<b:loop>

ループは var 属性に変数名、 values 属性にリストを指定します。
<b:loop var='i' values='data:posts'>
 <h2><data:i.title/></h2>
</b:loop>
また、 <b:include> を使って処理することもできます。
<b:loop var='p' values='data:posts'>
 <b:include name='EachPosting' data='p'/>
</b:loop>

<b:includable id='EachPosting' var='arg'>
 <data:arg.title/><br/>
</b:includable>


<b:skin>

CSS は <b:skin> タグの中に書きます。
<Variable> の name 属性に指定した名前を使って CSS に変数が使えます。
これはテンプレートデザイナーで簡単に変更できるという機能らしいです。

自分で使うだけというなら CSS ベタ書きで構いません。
しかし、ベタ書きの場合でも <b:skin> タグの中に書く必要があります。
<head>

<b:skin>
<![CDATA[
/*
 <Variable name="pgbgcolor"
  description="Page Background Color"
  type="color" default="#fff" value="#ffffff">
 <Variable name="pgtxtcolor"
  description="Page Text Color"
  type="color" default="#444" value="#444444">
*/

body {
 background: $pgbgcolor;
 color     : $pgtxtcolor;
 }
]]>
</b:skin>

</head>


<macro:> mexpr:

テンプレートの version2 では HTML5 対応?
<macro:> mexpr: も追加されてるのですが
ドキュメントが見当たらないのでよく分かりません。


参考サイト

レイアウト ガイド - Blogger ヘルプ
レイアウト用フォント タグとカラー タグ - Blogger ヘルプ
レイアウト用ページ要素タグについて - Blogger ヘルプ
レイアウト用ウィジット タグ - Blogger ヘルプ
レイアウト データ タグ - Blogger ヘルプ

Template of Doom
Bloggerテンプレートタグ一覧 - SNAPMAN
Blogger | egoblock
The Anatomy of a Blogger Layout (template) | fumbling in the dark

テンプレートデザイナーのHTML編集で過去記事一覧をサイドバーに出したい | Google グループ

Blogger の投稿フッターにはてなブックマーク件数を表示する方法
Bloggerのアーカイブページやラベルページで記事タイトル一覧を表示 :: Holiday Webmaster Blog

まとめるだけでお腹いっぱい。


- 追記 -

便利なところを見つけてしまった。
data: タグの値が見やすい。
blogger2ools

2012-04-05

バッチファイル入門

GUI に慣れてるととっつきにくいコマンドライン。
しかし、世の中には CUI しかないアプリケーションもあります。

毎回コマンドプロンプトから入力するのは大変ですが、
バッチファイルを作っておくとダブルクリックで実行できて便利。

今回は rtmpdump のバッチファイルを例に解説します。
::rtmpdump.bat

set rtmpdump="..\rtmpdump.exe"

%rtmpdump%^
 --rtmp     "rtmp://"^
 --tcUrl    ""^
 --app      ""^
 --playpath ""^
 --swfVfy   "http://"^
 --pageUrl  "http://"^
 --flashVer ""^
 --flv      ""


pause
exit


最初の行から解説していきますね。
::rtmpdump.bat

rem rtmpdump.bat
最初はコメント行です。
正式には rem のあとにコメントを書きます。

: はラベルの表記なのですが
:: はコメントの簡略表記として使われてるようです。
set rtmpdump="..\rtmpdump.exe"

%rtmpdump%^
次は変数 rtmpdump に値として rtmpdump.exe のパスをセットしてます。
フルパスでもバッチファイルからの相対パスでもOKです。

変数をコマンドとして展開する場合、スペースで区切られるので
パス名にスペースを含むときはダブルクォートで囲みましょう。

次に %rtmpdump% のように変数名を % で囲むと値が展開されます。

さて、rtmpdump にはこのあとオプションをいくつか渡す必要があります。
すると一行がえらく長くなって見づらいし、修正もしにくいので複数行に分けます。
単純に改行するとコマンドとして途切れてしまうので
改行を ^ (キャレット)でキャンセルします。
 --rtmp     "rtmp://"^
 --tcUrl    ""^
 --app      ""^
 --playpath ""^
 --swfVfy   "http://"^
 --pageUrl  "http://"^
 --flashVer ""^
 --flv      ""
先ほどの ^ (キャレット)を使ってオプションをこんな感じで書けます。
一行に書くより遙かに見やすいですね。

ここでも引数にスペースを含まない限り、 ダブルクォートで囲む必要はありませんが念のため囲ってます。

rtmpdump のオプションについてはドキュメントを読んでください。
pause
exit
ここはある意味肝です。

普通にバッチファイルをダブルクリックすると 実行後にコマンドプロンプトが閉じてしまうので
エラーが起きたのか成功したのかすら分かりません。
そこで、 pause を入れることで勝手に閉じるのを防げます。

exit はなくてもいいのですが、ここで終了するので このあとにコメントやメモを書いておけます。
オプションやヘルプなんかを貼っておくと便利ですね。

ここまで説明してなんですが、rtmpdump で検索して来たあなた。
RTMPExplorer を使った方が簡単ですよ。

@echo off
@echo off と書くと以後のコマンド入力が表示されなくなります。
出力だけ見たいときに書いておくとスッキリします。
rtmpdump のバッチでは変数展開をチェックしたいので書いてませんけど。
%rtmpdump%^
 -オプション^
 > output.txt 2>&1
出力を保存したいときはこんな感じでリダイレクトを使って、テキストファイルに書き出します。
リダイレクトの詳細は以下を参照してください。
コマンド リダイレクト演算子を使用する - microsoft


バッチパラメータ

バッチファイルは引数を使うことも出来ます。
%0 はバッチファイル名、%1 ~ %9 は引数で置換されます。

ドラッグアンドドロップしたファイル名は %1 になります。
@echo off
echo %1

pause
上のコードを C:\test.bat と保存してコマンドプロンプトから使う例です。
組み込みの環境変数 %date% を引数として渡してます。
C:\test.bat %date%

また、 %~(修飾子)(引数番号) とすると、ファイル名の一部を取り出したりできます。
@echo off

echo ファイル名
echo %~0
echo フルパス名
echo %~f0
echo ドライブ名
echo %~d0
echo パス名のみ
echo %~p0
echo ファイル名のみ
echo %~n0
echo 拡張子のみ
echo %~x0
echo ショートネーム
echo %~s0
echo ファイル属性
echo %~a0
echo ファイル日付
echo %~t0
echo ファイルサイズ
echo %~z0
echo.
echo ドライブ名 + パス名
echo %~dp0
echo ファイル名 + 拡張子
echo %~nx0
echo.

pause


日付・時間を使う

ファイル名などに日付・時間を入れたいこともありますね。
そんなときは、組み込みの環境変数 date、time を使います。

::datetime.bat
@echo off

echo 今日の日付
echo %date%
:: 2012/01/01

echo 現在時刻
echo %time%
:: 12:00:00.00

pause

ここで問題なのは / (スラッシュ)、 : (コロン) はファイル名に使えないことです。
要らないものは置換してしまいましょう。

書式は %変数名:置換対象文字列=置換後文字列% となります。
echo %date:/=%
:: 20120101

echo %time::=%
:: 120000.00

echo %date:/=%_%time::=%
:: 20120101_120000.00

このままで用が足りる場合もあるでしょうが、
細かく整形したい場合は抽出しちゃいましょう。

書式は %変数名:~m,n% (m,nは数字)となります。
m 文字目から n 文字を抽出します。
1番目の文字を 0 として数えることに注意。
m がマイナスの場合は、後ろから数えます。
set dt=%date%
set yyyy=%dt:~-10,4%
set mm=%dt:~-5,2%
set dd=%dt:~-2,2%

set date2=%yyyy%-%mm%-%dd%
echo %date2%
:: 2012-01-01

set tm=%time: =0%
set hh=%tm:~0,2%
set mm=%tm:~3,2%
set ss=%tm:~6,2%

set time2=%hh%-%mm%-%ss%
echo %time2%
:: 12-00-00

echo %date2%_%time2%
:: 2012-01-01_12-00-00

これで好きなように整形できますね。

補足しておくと、Windows2000では日付が
日 2012/01/01
のように曜日が頭に付くので、後ろから数えてます。

また、時間が1桁の場合
 1:00:00.00
のように頭にスペースが付くので 0 に置換します。


短く書きたい場合は
:: yyyy-mm-dd
echo %date:~-10,4%-%date:~-5,2%-%date:~-2,2%

:: Windows2000を考慮しない場合
echo %date:~0,4%-%date:~5,2%-%date:~8,2%

:: hh-mm-ss
set time2=%time: =0%
echo %time2:~0,2%-%time2:~3,2%-%time2:~6,2%



入門編としてはこれぐらい押さえておけばいいでしょう。
制御文やループを使いたいという方は参考サイトをどうぞ。


- 参考サイト -

コマンドライン リファレンス - microsoft
Windowsコマンドプロンプト基礎文法最速マスター - CX's Memo
バッチファイル基礎文法リファレンス - 学習ノート
連載:Windows 2000コマンドライン徹底活用 - @IT
バッチ・ファイル中で日付をファイル名に使用する - @IT

2012-04-04

Perl - WindowsでPerl

ワンライナー

ネットで見つけたワンライナーをコマンドプロンプトで使おうとすると
perl -e 'print "Hello, World!"'
Can't find string terminator "'" anywhere before EOF at -e line 1.
こんな感じでエラーが出て使えません。

引数はダブルクォートで囲わないとダメなので少し変更しないといけません。
# 内側のダブルクォートをエスケープする
perl -e "print \"Hello, World!\""

# qq 演算子を使う
perl -e "print qq{Hello, World!}"

# 内側のダブルクォートをシングルクォートに置き換える
perl -e "print 'Hello, World!'"

# q 演算子を使う
perl -e "print q{Hello, World!}"


perlへのショートカット

こんな感じでショートカットを作っておくと
ファイルをドラッグアンドドロップで実行できます。



バッチファイルでもできるのでお好きな方をどうぞ。
@echo off
cd /d "%~dp0"
cmd /k perl %1


UTF8を出力

現在では UTF8 でコードを書くのが主流ですが、
コマンドプロンプトの文字コードは CP932 なので
UTF8 で出力すると当然、文字化けします。

これは binmode で文字コードを CP932 にすれば大丈夫。
use strict;
use warnings;
use utf8;
binmode STDOUT => ':encoding(cp932)';

print "寿限無寿限無";
出力を UTF8 のまま得たい場合はテキストファイルに出力します。
use strict;
use warnings;
use utf8;
binmode STDOUT => ':utf8';

print "寿限無寿限無";
perl "C:\utf8.pl" > "C:\utf8.txt"
コマンドプロンプトの文字コードを UTF8 にする方法は
うまくいかない場合があるので、テキストファイルに出力した方が確実です。


秀丸でperl

秀丸マクロを覚えるのが面倒というあなたへ。
ちょこっと整形、置換、抽出したいときは 「その他 > プログラム実行」から perl が使えます。



ただ、これだと UTF8 でコードを書いた場合、shift-jis に変換されるのでうまくいきません。
この場合、下のように設定してください。
「Unicodeで標準入出力」は UTF-16 なのでチェックしません。



これは perl にファイル名を渡して cp932 で出力を受け取ります。
なのでファイルとして保存してから実行してください。
# サンプル
use strict;
use warnings;
use utf8;

binmode STDOUT => ':encoding(cp932)';
binmode STDERR => ':encoding(cp932)';

for my $line (<DATA>){
    chomp $line;
    print "僕と契約してよ、$line。\n";
}

__END__
うろぶち
きょうこ
まみ
まどか
さやか
ほむら
__END__ 以下は <DATA> で読み出せるので処理したいデータを貼り付けて
for なり while で回してゴニョゴニョします。

ちょろっとテキストを処理したいときなんか便利じゃないでしょうか。

2012-04-03

Perl - PACKAGEはブロックスコープじゃない

あまり使わないかもしれませんが、1つのファイルに複数の PACKAGE を書く場合注意が必要かなと。
use strict;
use warnings;

package FOO;
my $hoge = "madoka";

package BAR;
my $moge = "homura";

package BAZ;
print "\$FOO::hoge : $FOO::hoge \n";
print "\$hoge      : $hoge \n";
print "\$BAR::moge : $BAR::moge \n";
print "\$moge      : $moge \n";

------------------
実行結果
$FOO::hoge :        # エラー
$hoge      : madoka # 期待と違ってエラーじゃない
$BAR::moge :        # エラー
$moge      : homura # 期待と違ってエラーじゃない

Name "BAR::moge" used only once: possible typo at - line 12.
Name "FOO::hoge" used only once: possible typo at - line 10.
この場合 $hoge も $moge もレキシカル変数なので
外から見えないことを期待しましたが、なぜか見えます。

では、次の場合はどうでしょう?
use strict;
use warnings;

package FOO;
my $hoge = "madoka";

package BAR;
my $moge = "homura";

package BAZ;
my $hoge = "mami";
my $moge = "sayaka";

------------------
実行結果
"my" variable $hoge masks earlier declaration in same scope at - line 11.
"my" variable $moge masks earlier declaration in same scope at - line 12.
「$hoge も $moge も同じスコープで既に使われてるよ」と怒られます。
PACKAGE が違ってもレキシカル変数は同じスコープみたいです。

これはこれで不便なので期待通りに動かすには次のようにします。
package FOO;
{
    my $hoge = "madoka";
}
もしくは
{
    package FOO;
    my $hoge = "madoka";
}
このように明示的にブロックで囲みます。
これを踏まえて書き直すと
use strict;
use warnings;

package FOO;
{
    my $hoge = "madoka";
    print "\$hoge : $hoge \n\n";
}
package BAR;
{
    my $moge = "homura";
    print "\$moge : $moge \n\n";
}
package BAZ;
{
    my $hoge = "mami";
    my $moge = "sayaka";

    print "\$hoge : $hoge \n";
    print "\$moge : $moge \n";
}

------------------
実行結果
$hoge : madoka 

$moge : homura 

$hoge : mami 
$moge : sayaka 
めでたし、めでたし。


- 追記 -
perlのドキュメントに書いてありました。
perlmod - Perl のモジュール (パッケージとシンボルテーブル) 【perldoc.jp】

パッケージ文は(local() を使った)動的変数にのみ効果を持ちますが、
my() によって生成されたレキシカル変数には影響しません。

2010-12-01

FirefoxでDL時にメモリ使用量が増える問題の対処法

Firefoxで1GB程度のファイルをDLしようとすると800MBあたりでハングするという問題に遭遇。

何回か再現させてみるとメモリ不足っぽい症状になるので、
タスクマネージャーで見てみるとDL時にどんどんメモリ使用量が増加していく。
DLが800MBあたりになる頃にはメモリ使用量は1.2GBを突破。
明らかにおかしい。

いろいろとググってみると解決策そのものを発見。
知らなきゃ絶対損するPCマル秘ワザ DL時にFirefoxの使用メモリが増える症状 http://daredemopc.blog51.fc2.com/blog-entry-551.html
Problematic extensions - MozillaZine Knowledge Base http://kb.mozillazine.org/Problematic_extensions

Firebug 1.5.4 +?
Downloaded files will be stored in memory, possibly causing high memory use.
Disable Firebug when you don't need to use it
要するにFirebug 1.5.4使ってるとこの問題が起きるらしい。
対処法はFirebug 1.5.3を使うかFirebugを無効にする。

ということでFirebugを無効にしたら問題は発生しなくなりました。

-追記-
先日アップデートされたFirebug 1.6.0だとfixされてるようで
今のところ同じような現象は起きてません。

2010-04-11

Sleipnirスクリプトの変数汚染チェック

たまにしかプログラム書かないのでメモがてら実験。

一般的にブックマークレットなんかは変数汚染しないように
無名関数で実行するようになってますが
Sleipnir ではその辺どうなってるのかチェック。

まず、リンククリックで 変数str の値を表示するhtmlを用意。
(html,bodyタグを書くと投稿できなかったので補完してください。)

その次に 変数str の値を変更するスクリプトを用意。
/* Sleipnirスクリプト(WSH), UserActionスクリプト */
var pnir     = new ActiveXObject("Sleipnir.API");
var id       = pnir.GetDocumentID(pnir.ActiveIndex);
var window   = pnir.GetWindowObject(id);
var document = pnir.GetDocumentObject(id);

str = "fuga";
window.alert("str : " + str);
/* SeaHorseスクリプト (JavaScript) */
// ==UserScript==
// @name        変数汚染チェック (JavaScript)
// @include     *test.htm
// @description 変数汚染チェック (JavaScript)
// ==/UserScript== 

var pnir     = new ActiveXObject("Sleipnir.API");
var id       = pnir.GetDocumentID(pnir.ActiveIndex);
var window   = pnir.GetWindowObject(id);
var document = pnir.GetDocumentObject(id);

str = "fuga";
window.alert("str : " + str);
/* SeaHorseスクリプト (SleipnirScript) */
// ==UserScript==
// @name        変数汚染チェック (SleipnirScript)
// @include     *test.htm
// @description 変数汚染チェック (SleipnirScript)
// @type        SleipnirScript
// ==/UserScript== 

var pnir     = new ActiveXObject("Sleipnir.API");
var id       = pnir.GetDocumentID(pnir.ActiveIndex);
var window   = pnir.GetWindowObject(id);
var document = pnir.GetDocumentObject(id);

str = "fuga";
window.alert("str : " + str);
実行結果
Sleipnirスクリプト(WSH)
str : hoge // 変わらず

UserActionスクリプト
str : fuga // 変わった

SeaHorseスクリプト (JavaScript)
str : fuga // 変わった

SeaHorseスクリプト (SleipnirScript)
str : fuga // 変わった

Sleipnirスクリプト(WSH)以外は 変数str の値が変更されました。
WSH だと Sleipnir とは別スレッドで動くので影響を及ぼさないようです。

Sleipnirスクリプト(WSH)の場合、windowオブジェクト からたどらないと
アクセスできないので変数汚染の心配は少ない。
str = "fuga";
window.alert("str : " + str);
 ↓
window.str = "fuga";
window.alert("str : " + window.str); // fuga


では、次に var 宣言したらどうなるかの実験。
/* Sleipnirスクリプト(WSH), UserActionスクリプト */
var pnir     = new ActiveXObject("Sleipnir.API");
var id       = pnir.GetDocumentID(pnir.ActiveIndex);
var window   = pnir.GetWindowObject(id);
var document = pnir.GetDocumentObject(id);

var str = "fuga";
window.alert("var str : " + str);
/* SeaHorseスクリプト (JavaScript) */
// ==UserScript==
// @name var    var 変数汚染チェック (JavaScript)
// @include     *test.htm
// @description var 変数汚染チェック (JavaScript)
// ==/UserScript== 

var pnir     = new ActiveXObject("Sleipnir.API");
var id       = pnir.GetDocumentID(pnir.ActiveIndex);
var window   = pnir.GetWindowObject(id);
var document = pnir.GetDocumentObject(id);

var str = "fuga";
window.alert("var str : " + str);
/* SeaHorseスクリプト (SleipnirScript) */
// ==UserScript==
// @name        var 変数汚染チェック (SleipnirScript)
// @include     *test.htm
// @description var 変数汚染チェック (SleipnirScript)
// @type        SleipnirScript
// ==/UserScript== 

var pnir     = new ActiveXObject("Sleipnir.API");
var id       = pnir.GetDocumentID(pnir.ActiveIndex);
var window   = pnir.GetWindowObject(id);
var document = pnir.GetDocumentObject(id);

var str = "fuga";
window.alert("var str : " + str);
実行結果
Sleipnirスクリプト(WSH)
str : hoge // 変わらず

UserActionスクリプト
str : hoge // 変わらず

SeaHorseスクリプト (JavaScript)
str : fuga // 変わった

SeaHorseスクリプト (SleipnirScript)
str : hoge // 変わらず

SeaHorseスクリプト (JavaScript) だけ 変数str の値が変更されました。
ということはこんな感じなのかな。
// SeaHorseスクリプト (JavaScript)
window
 └ var str = "hoge";

// それ以外
window
 └ (function(){ var str = "hoge"; })();

結局のところ変数汚染が起こる場合もあるので
スクリプトは無名関数でラップして var 宣言しておくのが無難ですね。

2010-04-03

Sleipnir2.9.3 - ActiveXの妙なダイアログ

ActiveXの実行をオフにしてるとflashは実行されません。

この状態でflashの埋め込まれたページを開くと
デフォルトではTridentの情報バーが出るのですが、
鬱陶しいので情報バーをオフにしてます。

Sleipnir2.9.3にバージョン上げたら、今まで見たことないダイアログが。



なんじゃこれは?と調べてみたらありました。
2.9.3を導入後、ActiveXのダイアログが表示される - Fenrir User Community
%Sleipnir%/resources/languages/default/japanese/Client.ini

DialogActiveXTitle=Web ブラウザ 
↓ 
DialogActiveXTitle=Windows Internet Explorer 

こんな感じに変更すれば今まで通り。

2010-03-31

SleipnirでPerlを使う。

下準備

ActivePerl をインストール。

厳密には Perl じゃなくて PerlScript を使います。
ドキュメントは %perl%/html/Windows/WindowsScriptHost.html


Sleipnirスクリプト(WSH) で PerlScript を使う

%Sleipnir%/scripts/ に入れて使う方法。

標準では .pls に関連付けられているので
作ったものを hoge.pls など適当に名前をつけて保存。

%Sleipnir%/scripts/ に入れる。
メニューバー → スクリプト から実行。


.pls がプレイリストとバッティングしてる場合は
どう関連付けを変更すればいいのかわかりませんが

のような書き方で hoge.wsf として保存すれば実行できます。


UserActionスクリプト で PerlScript を使う

%Sleipnir%/plugins/scripts/ に入れて使う方法。

%Sleipnir%/resources/languages/default/english/ScriptEngine.ini
に追記することで対応言語を増やせるので
[StringTable]
js=JScript
vbs=VBScript
となっているのを
[StringTable]
js=JScript
vbs=VBScript
pl=PerlScript
と変更。

あとは作ったものを hoge.pl など適当に名前をつけて保存。
%Sleipnir%/plugins/scripts/
に入れればActionとして使えます。

もちろん Perl のモジュールも使い放題。
公式?の Sleipnir.pm というのもありますよ。

- 参考記事 -
UserAction Extension でオレオレスクリプトのススメ (1) (フェンリル | デベロッパーズブログ)
UserAction Extension でオレオレスクリプトのススメ (2) (フェンリル | デベロッパーズブログ)
UserAction Extension でオレオレスクリプトのススメ (3) (フェンリル | デベロッパーズブログ)
UserAction Extension でオレオレスクリプトのススメ (4) - そして伝説へ - (フェンリル | デベロッパーズブログ)
その後の「UserAction Extension でオレオレスクリプト」 (フェンリル | デベロッパーズブログ)

日本語使うとエラー出たりする

PerlScript で日本語が含まれると読み込まれるbyte数が短くなる。

PerlScript - miau's blog?
ActivePerlのPerlScriptで日本語
Bug 40776 – 2-byte character problem with PerlScript

これはうちの環境、winXP SP3、Sleipnir2.9.3、ActivePerl v5.10.1でも発生。
use strict;
use warnings;
use Win32::OLE;

my $pnir     = Win32::OLE->CreateObject("Sleipnir.API");
my $id       = $pnir->GetDocumentID($pnir->ActiveIndex);
my $window   = $pnir->GetWindowObject($id);
my $document = $pnir->GetDocumentObject($id);

if(!$document) {
 $pnir->Beep();
 $pnir->MessageBox("エラー:Documentオブジェクトが作成できませんでした");
} else {
 $pnir->Beep();
 $pnir->MessageBox("寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食う寝る処に住む処やぶら小路の藪柑子パイポパイポパイポのシューリンガンシューリンガンのグーリンダイグーリンダイのポンポコピーのポンポコナーの長久命の長助");
}

__END__ 
原因は内部処理で文字数とbyte数がごっちゃになってるせいらしい。
UTF8で書いても回避できません。

ずいぶんとほったらかしのバグですが、いまだに "Status: UNCONFIRMED" ってなんで?


解決するには
 1. 日本語を使わない。
 2. ファイル全体の文字数 > スクリプト部分のバイト数 になるようにスペース等を入れて調節する。
 3. require や use で動的・静的コンパイルする。
のどれかのようです。


では、動的・静的コンパイルを試してみましょう。
Sleipnir のインストール先は C:/sleipnir293/ とします。

Sleipnirスクリプト(WSH)
C:/sleipnir293/
 └ scripts/
  ├ JugemuPLS.pls
  ├ JugemuPM.pm
  ├ call_JugemuPLS.pls
  └ call_JugemuPM.pls

# JugemuPL.pl, JugemuPLS.pls, JugemuPM.pm
use strict;
use warnings;
use Win32::OLE;

my $pnir     = Win32::OLE->CreateObject("Sleipnir.API");
my $id       = $pnir->GetDocumentID($pnir->ActiveIndex);
my $window   = $pnir->GetWindowObject($id);
my $document = $pnir->GetDocumentObject($id);

if(!$document) {
 $pnir->Beep();
 $pnir->MessageBox("エラー:Documentオブジェクトが作成できませんでした");
} else {
 $pnir->Beep();
 $pnir->MessageBox('寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食う寝る処に住む処やぶら小路の藪柑子パイポパイポパイポのシューリンガンシューリンガンのグーリンダイグーリンダイのポンポコピーのポンポコナーの長久命の長助');
}

1;
__END__
# call_JugemuPLS.pls
use lib qw(C:/sleipnir293/scripts);
require 'JugemuPLS.pls';
# call_JugemuPM.pls
use lib qw(C:/sleipnir293/scripts);
use JugemuPM;

call_JugemuPLS.pls, call_JugemuPM.pm をそれぞれ実行。
Shift-JIS以外だと文字化けしますが、エラーは出ません。


UserActionスクリプト
C:/sleipnir293/
 └ plugins/
  └ scripts/
   ├ JugemuPL.pl
   ├ JugemuPM.pm
   ├ call_JugemuPL.pl
   └ call_JugemuPM.pl

# call_JugemuPL.pl
use lib qw(C:/sleipnir293/plugins/scripts);
require 'JugemuPL.pl';
# call_JugemuPM.pl
use lib qw(C:/sleipnir293/plugins/scripts);
use JugemuPM;

call_JugemuPL.pl, call_JugemuPM.pl をそれぞれ実行。
これもエラーは出ません。


もう少し何とかする
実行ファイル と 呼び出すファイル の2つが必要とはいえ
日本語がエラーなしで使えるのはありがたい。

そこでもう少し環境を詰めてみる。

.pm はモジュールなのでモジュール以外には使わない。

呼び出すファイルが
 Sleipnirスクリプト(WSH) は .pls
 UserActionスクリプト は .pl
というのは管理が煩雑になるので .pls に統一する。

Sleipnir.pm もあることだし %perl%/site/lib/Sleipnir/ 以下にスクリプトを放り込んでおけば
Sleipnirスクリプト(WSH) でも UserActionスクリプト でも
use lib しなくていいので便利かなと。

C:/perl/
 └ site/
  └ lib/
   ├ Sleipnir/
   │ ├ UAS_hoge.pls
   │ └ WSH_hoge.pls
   └ Sleipnir.pm
実行環境の違いも考慮するならこうした方がいいのかな。
C:/perl/
 └ site/
  └ lib/
   ├ Sleipnir/
   │ ├ UAS/
   │ │ └ UAS_hoge.pls
   │ └ WSH/
   │  └ WSH_hoge.pls
   └ Sleipnir.pm
C:/sleipnir293/
 ├ scripts/
 │ └ call_WSH_hoge.pls
 └ plugins/
  └ scripts/
   └ call_UAS_hoge.pls
ディレクトリで分けるかどうかはお好みで。


ということで変更点は3つ。

1. ScriptEngine.ini を編集。
C:/sleipnir293/resources/languages/default/english/ScriptEngine.ini

[StringTable]
js=JScript
vbs=VBScript
pl=PerlScript
pls=PerlScript
に変更して UserActionスクリプト で *.pls を実行できるように。


2. 実行ファイルと Sleipnir.pm を設置。
C:/perl/
 └ site/
  └ lib/
   ├ Sleipnir/
   │ ├ UAS_hoge.pls
   │ └ WSH_hoge.pls
   └ Sleipnir.pm
# 実行ファイルのテンプレはこんな感じで。
# 日本語が使えます。

# 一応 package 使った方がいいかも。
package Sleipnir::hoge;

use strict;
use warnings;
use Sleipnir;

my $pnir     = Sleipnir->new;
my $id       = $pnir->id;
my $window   = $pnir->window($id);
my $document = $pnir->document($id);

if(!$document) {
 $pnir->Beep();
 $pnir->MessageBox("エラー:Documentオブジェクトが作成できませんでした");
} else {
 # code
}

# この 1 は必須です。
1;
__END__

3. 呼び出すファイル(*.pls)を設置して実行。
C:/sleipnir293/
 ├ scripts/
 │ └ call_WSH_hoge.pls
 └ plugins/
  └ scripts/
   └ call_UAS_hoge.pls
require 'Sleipnir/WSH_hoge.pls';
require 'Sleipnir/UAS_hoge.pls';

__END__
# 呼び出すファイルのテンプレはこんな感じで。
# 日本語でコメントを書く場合は __END__ 以下に書けます。


実際に動かしてみる
C:/perl/
 └ site/
  └ lib/
   ├ Sleipnir/
   │ └ Jugemu.pls
   └ Sleipnir.pm
C:/sleipnir293/
 ├ scripts/
 │ └ call_Jugemu.pls
 └ plugins/
  └ scripts/
   └ call_Jugemu.pls
# Jugemu.pls
package Sleipnir::Jugemu;

use strict;
use warnings;
use Sleipnir;

my $pnir     = Sleipnir->new;
my $id       = $pnir->id;
my $window   = $pnir->window($id);
my $document = $pnir->document($id);

if(!$document) {
 $pnir->Beep();
 $pnir->MessageBox("エラー:Documentオブジェクトが作成できませんでした");
} else {
 $pnir->Beep();
 $pnir->MessageBox('寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食う寝る処に住む処やぶら小路の藪柑子パイポパイポパイポのシューリンガンシューリンガンのグーリンダイグーリンダイのポンポコピーのポンポコナーの長久命の長助');
}

1;
__END__
# call_Jugemu.pls
require 'Sleipnir/Jugemu.pls';

__END__
これでもShift-JIS以外は文字化けするので
文字コードが問題になるのなら
UTF8で書いてShift-JISで出力すればOK。
# JugemuUTF8.pls
package Sleipnir::JugemuUTF8;

use utf8;
use strict;
use warnings;
use Encode qw/encode/;

use Sleipnir;

my $pnir     = Sleipnir->new;
my $id       = $pnir->id;
my $window   = $pnir->window($id);
my $document = $pnir->document($id);

if(!$document) {
 my $txt = 'エラー:Documentオブジェクトが作成できませんでした';
 $txt = encode('Shift_JIS', $txt);

 $pnir->Beep();
 $pnir->MessageBox($txt);
} else {
 my $txt = '寿限無寿限無五劫の擦り切れ海砂利水魚の水行末雲来末風来末食う寝る処に住む処やぶら小路の藪柑子パイポパイポパイポのシューリンガンシューリンガンのグーリンダイグーリンダイのポンポコピーのポンポコナーの長久命の長助';

 $txt = encode('Shift_JIS', $txt);

 main::MsgBox($txt);

 $window->alert($txt);

 $pnir->Beep();
 $pnir->MessageBox($txt);
}

1;
__END__

こんな感じでいかがでしょうか?
早くバグ修正してくれないかなー。


- 関連記事 -
Aragger: Sleipnirのスクリプトがわかりにくいので整理してみる。

Sleipnirのスクリプトがわかりにくいので整理してみる。

Sleipnirのスクリプトがわかりにくいので整理してみる。

スクリプトが置ける場所は以下の4つ。
%Sleipnir% は Sleipnir のインストールフォルダ。
%Sleipnir%/bookmarklet/
%Sleipnir%/scripts/
%Sleipnir%/plugins/scripts/
%Sleipnir%/plugins/seahorse/

■ %Sleipnir%/bookmarklet/

[使用言語] JavaScript

アドレスバー拡張メニュー用のスクリプトを置くフォルダ。
お気に入りのブックマークレットとは関係ない。

セキュリティで「JavaScript の実行を許可」しないと使えない。

タブブラウザ Sleipnir オンラインデータベース(各部の名称と使い方) - アドレスバー拡張メニュー
タブブラウザ Sleipnir オンラインデータベース(Tips) - アドレスバー拡張メニューの編集


■ %Sleipnir%/scripts/

[使用言語] JavaScript, VBScript, 他

Sleipnir 1.xx互換スクリプト(WSHスクリプト)を置くフォルダ。
メニューバーの「スクリプト」から利用できる。
「Sleipnir オプション→クライアント→全般」の「スクリプトによるクライアントの操作を許可する」を有効にしないと使えない。

フォルダ名の先頭が「$」になっているフォルダは、メニューバーの「スクリプト」に表示されない。
以下のフォルダには特別な役割がある。

%Sleipnir%/scripts/$AdvancedPageSearchBar
ページ検索バーの「拡張スクリプトを実行」ボタンから使用するスクリプトを置くフォルダ。

%Sleipnir%/scripts/$OnDoubleClick
アウトプットDockをダブルクリックした場合に呼び出されるスクリプトを置くフォルダ。
このフォルダ内のスクリプトは、他のスクリプトから呼び出される形で使用される。

タブブラウザ Sleipnir オンラインデータベース(スクリプト)
タブブラウザ Sleipnir オンラインデータベース(Sleipnir.API リファレンス)
タブブラウザ Sleipnir オンラインデータベース(スクリプトの開発)
タブブラウザ Sleipnir オンラインデータベース(Sleipnirスクリプト作成法)
タブブラウザ Sleipnir オンラインデータベース(スクリプトの開発 FAQ)
タブブラウザ Sleipnir オンラインデータベース(スクリプトの開発 Tips)

■ %Sleipnir%/plugins/scripts/

[使用言語] JavaScript, VBScript, 他

UserAction Extensionをインストールすると作成される。
UserActionスクリプト(Sleipnir組み込みスクリプト)を使用する場合は、スクリプトをここに置く。

%Sleipnir%/plugins/scripts/embedded
Hawkeye等をインストールすると作成される。
特定プラグイン用のSleipnir組み込みスクリプトが置かれる。

タブブラウザ Sleipnir オンラインデータベース(Sleipnir.API リファレンス)
タブブラウザ Sleipnir オンラインデータベース(UserActionスクリプト)
タブブラウザ Sleipnir オンラインデータベース(組み込みスクリプトの書き方)
タブブラウザ Sleipnir オンラインデータベース(スクリプトの開発 Tips) - UserAction スクリプトを wscript.exe で実行する

■ %Sleipnir%/plugins/seahorse/

[使用言語] JavaScript

SeaHorseをインストールすると作成される。
SeaHorseスクリプトを使用する場合は、SeaHorseスクリプト(*.user.js)をここに置く。

JavaScript を描画エンジンが処理するため、セキュリティで「JavaScript の実行を許可」しないと動作しない。


ヘッダに以下の行を追加するとSleipnirScriptとして動作。
// @type SleipnirScript
この場合、「JavaScript の実行を許可」 は関係ないが
「スクリプトによるクライアントの操作を許可する」を有効にしないと使えない。

タブブラウザ Sleipnir オンラインデータベース(SeaHorseスクリプト)
タブブラウザ Sleipnir オンラインデータベース(Sleipnir.API リファレンス)
タブブラウザ Sleipnir オンラインデータベース(組み込みスクリプトの書き方)
Fenrir User Community - SeaHorseのJSからVBSを呼び出す方法



スクリプト実行環境

Sleipnirにはスクリプト実行環境が3つある。

1. ブラウザの描画エンジン(Trident, Gecko)

[使用言語] JavaScript

[実行パス]
%Sleipnir%/bookmarklet/
%Sleipnir%/plugins/seahorse/
お気に入りのブックマークレット


2. Windows Script Host(WSH)

[使用言語] JavaScript, VBScript, 他

[実行パス]
%Sleipnir%/scripts/

標準でJavaScript、VBScriptに対応。
環境依存になるが、Windows Script Host(WSH)で動く言語なら何でも使える。

実行されるスクリプトは
・Sleipnirスクリプト
・Sleipnir1.xx互換スクリプト
・WSHスクリプト
などと呼ばれる。


3. SleipnirScript

[使用言語] JavaScript, VBScript, 他

[実行パス]
%Sleipnir%/plugins/scripts/
%Sleipnir%/plugins/seahorse/

Sleipnirに独自に実装されている、スクリプト実行環境。
SleipnirScript≠Sleipnirスクリプト(WSH)と非常にまぎらわしい。
WSH を介さずメインスレッドで動作するので高速。

一方で
・WSH のプロパティ・メソッドが使えない。
・Sleep() でブラウザの全ての処理が止まってしまうため、
 ページの読み込みを待つ等の処理ができない。
という短所がある。

実行されるスクリプトは
%Sleipnir%/plugins/scripts/ 以下なら
・Sleipnir組み込みスクリプト
・UserActionスクリプト

%Sleipnir%/plugins/seahorse/ 以下なら
・SeaHorseスクリプト
などと呼ばれる。


%Sleipnir%/resources/languages/default/english/ScriptEngine.ini
に追記することで対応言語を増やせる。
[StringTable]
js=JScript
vbs=VBScript
となっているので
拡張子=スクリプト名
と追記する。

- Ruby
sleipnir-api-0.4.1 Documentation

- Perl
UserAction Extension でオレオレスクリプトのススメ (1) (フェンリル | デベロッパーズブログ)
UserAction Extension でオレオレスクリプトのススメ (2) (フェンリル | デベロッパーズブログ)
UserAction Extension でオレオレスクリプトのススメ (3) (フェンリル | デベロッパーズブログ)
UserAction Extension でオレオレスクリプトのススメ (4) - そして伝説へ - (フェンリル | デベロッパーズブログ)
その後の「UserAction Extension でオレオレスクリプト」 (フェンリル | デベロッパーズブログ)




関連用語をチェック

タブブラウザ Sleipnir オンラインデータベース(用語辞典)

■ SeaHorse Extension 【しーほーす・えくすてんしょん】[名] †
Sleipnir 2.xx用のプラグイン。

このプラグインを使用すると、ページ読み込み完了時にスクリプトを自動実行できるようになる。
主に表示前のソースを改変する目的で使われる。
「ブックマークレットを自動実行してくれるもの」
「Webページを受信側で勝手に書き換えられるようになるもの」と考えるとわかりよい。

スクリプト次第で、「一部のフォントを変える」といった小規模な調整から、
「異なるページを接合して1ページに表示する」といった大規模な改変まで可能になる。

ただし「スクリプト使用数が多いとSleipnirの動作が重くなる」
「スクリプトの不具合により想定外の支障が起こりうる」といったリスクも発生する。
セキュリティやモラルの問題もあり、使用に際してはある程度の見識が求められる。

SeaHorse Extensionで使用するスクリプトプログラムは「SeaHorseスクリプト」と呼ばれる。
SeaHorseスクリプトは基本的に「JavaScriptとして記述」し「描画エンジンで動作」するものだが、
目的によっては「Sleipnir組み込みスクリプトとして記述」し「SleipnirScriptで動作」させることもできる。

■ Sleipnir.API 【すれいぷにる-えー・ぴー・あい】[名] †
Sleipnirの機能拡張プログラム(Sleipnir用スクリプト、Sleipnir組み込みスクリプト、Sleipnir用プラグイン)が
利用できる、Sleipnir用の特殊な関数のこと。
これを活用すると、Sleipnirの状態を調べたり、Sleipnirに指示を出したりできる。

Sleipnir 1.xx にも 2.xx にも組み込まれているが、両方のバージョンの併用はできず、
どちらか片方のバージョンの Sleipnir.API しか呼び出せないようになっている。

「API」は「Application Programming Interface」の略。

■ Sleipnir スクリプト 【すれいぷにる-すくりぷと】[名] †
Sleipnir専用の機能拡張スクリプト。
Sleipnirの機能を拡張する方法のひとつ。
比較的小~中規模の機能実現に適している。

「Sleipnir用スクリプト」「1.xx 互換スクリプト」「WSH スクリプト」とも言われる。
SleipnirScriptとは別物なので注意。

Sleipnirの機能を拡張する方法としてはSleipnir用プラグインがあるが、
Sleipnirスクリプトはプラグインよりも手軽に作成でき、かつ導入も容易である。
またSleipnirスクリプトは、Sleipnir本体と連携を行うための仕組み「Sleipnir.API」を活用できるため、
ブックマークレットよりも緊密な機能を実現することができる。
スクリプトの作成言語には JScript と VBScript が使用可能。

Sleipnirスクリプトを利用するには、
「Sleipnir オプション→クライアント→全般」の
「スクリプトによるクライアントの操作を許可する」を有効にする必要がある。
これによりメニューバーの「スクリプト」からSleipnirスクリプトを実行できるようになる。

■ Sleipnir 組み込みスクリプト 【すれいぷにる-くみこみ-すくりぷと】[名] †
スクリプト実行環境「SleipnirScript」上で実行されるSleipnir用スクリプト。
Sleipnirの機能を拡張することができる。
メニューバーの「スクリプト」から使用するSleipnirスクリプトとは別物なので注意。

スクリプトの作成、実行にあたっては以下のような特徴がある。

・Sleipnir.APIを使用できる(レジストリへの登録と Sleipnir オプションの設定が必要)。
・Sleipnirに搭載されているデータベースエンジン「SQL」を使用できる。
・作成言語にはJScriptかVB スクリプトが使用可能。
・スクリプトの実行は、Sleipnir 2.xxに独自に実装されているスクリプト実行環境「SleipnirScript」で行われる。

wscript.exe は利用しないため、従来のSleipnir スクリプトと互換性が無い。
つまり「機能拡張スクリプト」全般のことではなく、
その中でも「SleipnirScriptという実行エンジン上で動作するスクリプト」のこと。

具体的には、
・UserAction Extensionで使用するスクリプト
・SleipnirScriptで実行するよう指定されているSeaHorse用スクリプト
以上が「Sleipnir組み込みスクリプト」である。

■ SleipnirScript 【すれいぷにる-すくりぷと】[名] †
Sleipnirに独自に実装されている、スクリプト実行環境。
「Sleipnir 組み込みスクリプト」を実行できる機構。
実行エンジンにWindows Script Host(WSH)を使用した従来の方式と異なり、
高速かつ安全にスクリプトを実行できるとされている。

広義には、実行対象である「Sleipnir 組み込みスクリプト」そのものを指すこともある。
技術的な話題では混同に注意。

■ UserAction Extension 【ゆーざー-あくしょん・えくすてんしょん】[名] †
Sleipnir 2.xx用のプラグイン。
このプラグインを使用すると、Sleipnir組み込みスクリプトをアクションとして扱えるようになる。
例えば、スクリプトをキーボードショートカットやマウスジェスチャから実行できるようになる。

メニューバーの「スクリプト → スクリプトの整理」とはスクリプトファイルの設置場所が違うので注意すること。

■ Windows Script Host 【うぃんどうず-すくりぷと-ほすと】[名] †
略称「WSH」。
Windows上でスクリプトプログラム(~.js、~.vbs等)を実行できる仕組み。
最近のWindows PCには標準で搭載されている。
手軽に使えるが、ファイル削除、レジストリの書き換えなども行えるため、
WSHで実行されるスクリプトは実行ファイル(~.exe等)と同等の危険性も持つ。

Sleipnirの「メニューバー → スクリプト」で動作させるスクリプト(Sleipnirスクリプト)は
このWSH上で動作している(Sleipnir組み込みスクリプトとは別物なので注意)。

■ スクリプト 【すくりぷと】[名] †
スクリプト言語と呼ばれるプログラミング言語で作成された一種のプログラムの事。

Sleipnirが扱うスクリプトは大きく分けて二種類ある。

ひとつはWebページの製作者が用意するスクリプトで、一般的には JavaScript が使われる。
主にWebページに動きを与える目的で使用されており、基本的にどのWebブラウザでも使用可能。
HTMLファイル等とともにレンダリングエンジンに読み込まれ処理している。
レンダリングエンジンが処理をするという意味では、ブックマークレットもこちらに含まれる。

もうひとつはローカル(HDD上など)に置いたスクリプトファイル(拡張子 .js .vbs)をメニューバーなどから呼び出して使用する
Sleipnir専用のスクリプトであり、Sleipnir でスクリプトと言えば主にこちらの意味で使われることが多い。
こちらはレンダリングエンジンではなくWindows Script Host(WSH))が処理し、
WebページはもとよりSleipnirやOSの制御が可能で、Sleipnir にさまざまな機能をユーザーが独自に追加することができる。

ただし、このSleipnir独自のスクリプト機能は高い柔軟性を持つ一方、
悪意のあるスクリプトを作成することも可能なため、実行の際は注意を払う必要がある。
故に、入手元が信用できないスクリプトは使わない方が良い。

■ ブックマークレット 【ぶっくまーくれっと】[名] †
ブックマーク(お気に入り)に、URLではなくJavaScriptを登録しておくこと。
そのブックマークを開くと、記しておいたスクリプトが実行される。

Sleipnirはブックマークレットに対応しており、
お気に入りをクリックした時に新しいウィンドウを開く設定にしていても、
ブックマークレットをクリックした場合は新しいウィンドウを開かず
アクティブなウィンドウに対してスクリプトを実行する仕組みが取り入れられている。

なお、アドレスバー拡張メニューについてもアクション名やフォルダ名に何故か「bookmarklet」という単語が用いられている。
混同しないよう注意(基本的には同じスクリプトを実行できる)。

タブブラウザ Sleipnir オンラインデータベース(Sleipnir2 フォルダ構成)

■ %Sleipnir%/bookmarklet/
アドレスバー拡張メニュー用のスクリプトを納めるフォルダです。
具体的な使用法については「各部の名称と使い方|アドレスバー拡張メニュー」
「Tips|アドレスバー拡張メニューの編集」をご覧下さい。

まぎらわしいですが、お気に入り内のブックマークレットとは関係ありません。

■ %Sleipnir%/plugins/
以下のフォルダは初期状態では存在しません。
特定のプラグインを追加すると作成、使用されます。

■ %Sleipnir%/plugins/scripts/
・UserAction Extensionをインストールすると作成される
・UserActionスクリプト(Sleipnir組み込みスクリプト)を使用したい場合は、スクリプトファイルをここに入れる

■ %Sleipnir%/plugins/scripts/embedded/
・Hawkeye等をインストールすると作成される
・特定プラグイン用のSleipnir組み込みスクリプトが置かれる

■ %Sleipnir%/plugins/seahorse/
・SeaHorseをインストールすると作成される
・SeaHorseスクリプトを使用したい場合は、SeaHorseスクリプト(~.user.js)をここに入れる

■ %Sleipnir%/scripts/
Sleipnir用の1.xx互換スクリプト(WSHスクリプト)が納められています。
拡張子「.js」「.vbs」のファイルをここに入れると、メニューバーの「スクリプト」から利用できます。
スクリプトについての詳細は「スクリプト」をご覧下さい。

フォルダ名の先頭が「$」になっているフォルダは、メニューバーの「スクリプト」に表示されません。
以下のフォルダには特別な役割があります。

$AdvancedPageSearchBar
ページ検索バーの「拡張スクリプトを実行」ボタンから使用するスクリプトを納めるフォルダです。

$OnDoubleClick
アウトプットDockをダブルクリックした場合に呼び出されるスクリプトを納めるフォルダです。
このフォルダ内のスクリプトは、他のスクリプトから呼び出される形で使用されます。



スクリプト作成 参考リンク

Fenrir User Community - Developer フォーラム (SLDEV)
プヨぷよの日記
由々識の気まぐれ日記
Sleipnir Assembly House for Kittens - Sleipnir Syndication
Yuyu's Digital Lab.
Sleipnir Unofficial Script Page
Sleipnirist
cubic9.com - Sleipnir_Script
Sleipnir2スレ
958lab
958 Wiki*
ここここあ