<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="/style/rss.xsl" type="text/xsl"?>
<rdf:RDF
	xmlns="http://purl.org/rss/1.0/"
	xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:admin="http://webns.net/mvcb/"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/"
	xml:lang="ja"
>
	<channel rdf:about="http://www.akatsukinishisu.net/itazuragaki/index.rss">
		<title>徒書</title>
		<link>http://www.akatsukinishisu.net/itazuragaki/</link>
		<description>徒に何か書いています。</description>
		<image rdf:resource="http://www.akatsukinishisu.net/akashy.png" />
		<dc:creator>北村曉</dc:creator>
		<admin:generatorAgent rdf:resource="http://www.raelity.org/apps/blosxom/?v=2.0"/>
		<items>
			<rdf:Seq>
				<rdf:li rdf:resource="http://www.akatsukinishisu.net/itazuragaki/html/html5_elements_in_IE_without_conditional_comment.html"/>
				<rdf:li rdf:resource="http://www.akatsukinishisu.net/itazuragaki/perl/i20110103.html"/>
				<rdf:li rdf:resource="http://www.akatsukinishisu.net/itazuragaki/perl/to_what_does_weaken_work.html"/>
				<rdf:li rdf:resource="http://www.akatsukinishisu.net/itazuragaki/perl/instmodsh.html"/>
				<rdf:li rdf:resource="http://www.akatsukinishisu.net/itazuragaki/perl/overwrite_method.html"/>
			</rdf:Seq>
		</items>
	</channel>

	<image rdf:about="http://www.akatsukinishisu.net/akashy.png">
		<title>アカシーくん</title>
		<link>http://www.akatsukinishisu.net/itazuragaki/</link>
		<url>http://www.akatsukinishisu.net/akashy.png</url>
	</image>

	<item rdf:about="http://www.akatsukinishisu.net/itazuragaki/html/html5_elements_in_IE_without_conditional_comment.html">
		<title>HTML5の要素を条件付きコメントなしでIEで使う</title>
		<link>http://www.akatsukinishisu.net/itazuragaki/html/html5_elements_in_IE_without_conditional_comment.html</link>
		<dc:subject>HTML</dc:subject>
		<dc:creator>北村曉</dc:creator>
		<dc:date>2012-01-09T02:42:00+09:00</dc:date>
		<trackback:ping rdf:resource="http://www.akatsukinishisu.net/itazuragaki/html/html5_elements_in_IE_without_conditional_comment.tb"/>
		<description>今更ながら、ここもHTML5にしてみようかなという気持ちが湧いてきています。以前は、一旦公開した文書の形式を無闇に変えるのはよくないという思いが強かったのですが、個人のページなのだし色々と実験的なことをもっと試してもいいのでは、と思うようになったので。さて、HTML5導入にあたり一番気にしていたのが、IEでHTML5の新しい要素を使う方法のことでした。...</description>
		<content:encoded><![CDATA[

<p>今更ながら、ここもHTML5にしてみようかなという気持ちが湧いてきています。以前は、一旦公開した文書の形式を無闇に変えるのはよくないという思いが強かったのですが、個人のページなのだし色々と実験的なことをもっと試してもいいのでは、と思うようになったので。</p>

<p>さて、HTML5導入にあたり一番気にしていたのが、IEでHTML5の新しい要素を使う方法のことでした。今だと <a href="http://code.google.com/p/html5shiv/" title="html5shiv - HTML5 IE enabling script - Google Project Hosting">html5shiv</a> を使って以下のようなコメントを入れるのが一般的になっているようです。</p>

<pre>&lt;!--[if lt IE 9]&gt;
&lt;script src="//html5shiv.googlecode.com/svn/trunk/html5.js"&gt;&lt;/script&gt;
&lt;![endif]--&gt;</pre>

<p>しかしながら、HTML文書というのは様々な環境で利用されるための文書形式だと自分は考えているので、その中に(コメントとは言え)特定のブラウザのための記述を入れることには抵抗があったのでした。そこで、上記のような<em>条件付きコメントを使わずに</em>、IEでHTML5の新しい要素を使う方法をここ数日模索しており、何とか方法が見つかりましたので以下に紹介する次第です。</p>

<p>ひとまずサンプルをどうぞ。</p>

<ul>
<li><a href="http://www.akatsukinishisu.net/itazuragaki/data/html/html5_elements_in_IE_without_conditional_comment/html5htc.html">HTML5 Shiv HTC test</a> (html5htc.html)</li>
</ul>

<p>他に使用しているファイルは以下の通りです。</p>

<ul>
<li><a href="http://www.akatsukinishisu.net/itazuragaki/data/html/html5_elements_in_IE_without_conditional_comment/ie.css">ie.css</a></li>
<li><a href="http://www.akatsukinishisu.net/itazuragaki/data/html/html5_elements_in_IE_without_conditional_comment/html5.htc">html5.htc</a></li>
</ul>

<p>見ての通り、以前に<a href="http://www.akatsukinishisu.net/itazuragaki/css/nifty_corners_behavior.html" title="border-radius + -moz-border-radius + (Nifty Corners * IE behavior) - 徒書">角丸の表示</a>で利用していた、IEの <a href="http://msdn.microsoft.com/ja-jp/library/ms532146(v=vs.85).aspx" title="HTML Components を使った DHTML Behaviors のスクリプトによる実装">DHTML Behaviors</a> を利用しました。これだとHTML文書に適用するCSSの中で、</p>

<pre><code>body {
  behavior:url(./html5.htc);
}</code></pre>

<p>というようなルールを追加するだけなので、HTML5文書自体には余計な記述を追加することなく利用できます。</p>

<p>なお、html5.htc の中では <a href="http://code.google.com/p/html5shiv/" title="html5shiv - HTML5 IE enabling script - Google Project Hosting">html5shiv</a> のコードをほぼそのまま利用しています。</p>

<div class="divider">* * *</div>

<p>この html5.htc を作る過程の試行錯誤で、2点ほど学んだことがあったので覚え書き。</p>

<p><strong>htcファイルの中から、HTML文書のdocumentオブジェクトは直接参照できない。</strong> htcファイルのscript要素で <var>document</var> と書くと、それは「htcファイルのdocumentオブジェクト」ということになるようです。一方、behavior を適用した要素(body要素)は <var>element</var> で参照できるので、<em>HTML文書の</em> document オブジェクト、window オブジェクトを得るには以下のようにする必要がありました。</p>

<pre><code>var doc = element.document;
var win = doc.parentWindow;</code></pre>

<p><strong>最後に element.innerHTML の更新が必要。</strong> これをしなくてもhtcファイルのscript要素のスクリプトは実行されていたので、それで問題ないように思っていたのですが、実際はそれだけだとスタイルが適用されませんでした。色々試す中で、半ば自棄で <code>element.innerHTML = element.innerHTML</code> というコードを入れてみたところ、思いがけずそれでうまく行ってしまったのでした。おそらく代入によりHTML5新要素のタグが改めて解析されたのだろうと推測しますが、自身を代入することで結果が変わるというのは何とも不思議な感じです。</p>

<ins datetime="2012-01-09T20:29:00+09:00"><p>コードをより短くするため、<code>element.innerHTML += ''</code> と変更しました。</p></ins>
]]></content:encoded>
	</item>
	<item rdf:about="http://www.akatsukinishisu.net/itazuragaki/perl/i20110103.html">
		<title>Mojolicious wikiにあるORLiteの例をUnicode対応にする</title>
		<link>http://www.akatsukinishisu.net/itazuragaki/perl/i20110103.html</link>
		<dc:subject>Perl</dc:subject>
		<dc:creator>北村曉</dc:creator>
		<dc:date>2011-01-03T23:56:00+09:00</dc:date>
		<trackback:ping rdf:resource="http://www.akatsukinishisu.net/itazuragaki/perl/i20110103.tb"/>
		<description>[Mojolicious::LiteでData::Modelを使ってみた]という記事で、【引用: MojoliciousのWikiにORLiteを使ったサンプルがあったのですが、残念ながらそのままでは日本語には対応していないので、…】という文を見かけたので、その [Working with ORLite inside Mojolicious] にあるサンプルを日本語でも使えるようにできないか、調べてみました。Mojolicious::Liteにおける文字エンコーディング周りの...</description>
		<content:encoded><![CDATA[

<p><a href="http://weblog.nqou.net/archives/20110102205559.html" title="Mojolicious::LiteでData::Modelを使ってみた - 日曜プログラマのそゞろ事">Mojolicious::LiteでData::Modelを使ってみた</a>という記事で、</p>

<blockquote cite="http://weblog.nqou.net/archives/20110102205559.html" title="Mojolicious::LiteでData::Modelを使ってみた - 日曜プログラマのそゞろ事">
<p>MojoliciousのWikiにORLiteを使ったサンプルがあったのですが、残念ながらそのままでは日本語には対応していないので、…</p>
</blockquote>

<p>という文を見かけたので、その <a href="https://github.com/kraih/mojo/wiki/Using-orlite" title="Working with orlite inside mojolicious - mojo - GitHub">Working with ORLite inside Mojolicious</a> にあるサンプルを日本語でも使えるようにできないか、調べてみました。</p>

<p>Mojolicious::Liteにおける文字エンコーディング周りの動作を調べてみたところ、Mojolicious::Liteの内部では、文字列はあくまでPerlの内部文字列として扱われることを知りました。具体的に言うと:</p>

<ul>
<li>GET または POST されたデータは、自動的に内部文字列に変換される。</li>
<li>テンプレートデータは内部文字列として保持され、出力時にまとめて特定の文字エンコーディング(UTF-8等)に変換される。</li>
</ul>

<p>なので、 $self-&gt;param('type') のようにして取得したデータは、その時点で内部文字列となっているし、また、データベースから取得したデータをテンプレートに埋め込むならば、内部文字列とした上で埋め込む必要がある、ということになります。</p>

<p>そうすると修正はデータベース寄りということになりそうです。調べると、<a href="http://search.cpan.org/dist/ORLite/lib/ORLite.pm" title="ORLite - search.cpan.org">ORLite</a>が使用するDBD::SQLiteには、入出力データを内部文字列として扱うための属性(<a href="http://search.cpan.org/dist/DBD-SQLite/lib/DBD/SQLite.pm#Unicode_handling" title="DBD::SQLite - search.cpan.org">sqlite_unicode</a>)がありました。しかしORLiteではその属性を使用していないようです。</p>

<p>そこで、以下のように package Model のところで connect メソッドを上書きすることで、日本語文字列のポスト・表示にも対応することができました。</p>

<ins datetime="2012-02-03T14:55:46+09:00">
<p>追記(2012年2月3日): <a href="http://search.cpan.org/dist/ORLite/lib/ORLite.pm" title="ORLite - search.cpan.org">ORLite</a> がバージョン1.52以降で <code>unicode</code> オプションをサポートしたため、以下のソースも変更しました。</p>
</ins>

<pre><code>#!/usr/bin/env perl

package Model;
use strict;
use ORLite {
    file   =&gt; 'sample.db',
    create =&gt; sub {
        my $dbh = shift;
        $dbh-&gt;do(
            'CREATE TABLE motorcycles (
             id INTEGER PRIMARY KEY,
             type TEXT NOT NULL, 
             brand TEXT NOT NULL,
             color TEXT)'
        );

        # just use $dbh-&gt;do(...) if you need more
        # tables
        return 1;
    },
    # ORLite &gt;= 1.52
    unicode =&gt; 1,
};

#{
#    # use unicode character (ORLite &lt; 1.52)
#    my $connect = sub {
#        DBI-&gt;connect( $_[0]-&gt;dsn, undef, undef, {
#            PrintError =&gt; 0,
#            RaiseError =&gt; 1,
#            sqlite_unicode =&gt; 1,
#        } );
#    };
#    no warnings 'redefine';
#    *connect = $connect;
#}

package main;

use Mojolicious::Lite;
use utf8;

get '/' =&gt; sub {
    my $self = shift;
    $self-&gt;stash(motorbikes =&gt; [Model::Motorcycles-&gt;select('order by type')]);
} =&gt; 'index';

post '/' =&gt; sub {
    my $self = shift;
    Model::Motorcycles-&gt;create(
        type  =&gt; $self-&gt;param('type'),
        brand =&gt; $self-&gt;param('brand'),
        color =&gt; $self-&gt;param('color')
    );
    $self-&gt;redirect_to('/');
};

app-&gt;start;

__DATA__

@@ index.html.ep
&lt;!DOCTYPE html&gt;
&lt;html&gt;
  &lt;head&gt;
    &lt;title&gt;Motorcycles&lt;/title&gt;
    &lt;style&gt;td { background-color:#dee; } &lt;/style&gt;
  &lt;/head&gt;
  &lt;body&gt;
    &lt;h1&gt;Motorcycles&lt;/h1&gt;
    &lt;table&gt;
    % foreach my $cycle (@{$motorbikes} ) {
      &lt;tr&gt;
        &lt;td&gt;&lt;%= $cycle-&gt;type %&gt;&lt;/td&gt;
        &lt;td&gt;&lt;%= $cycle-&gt;brand %&gt;&lt;/td&gt;
        &lt;td&gt;&lt;%= $cycle-&gt;color %&gt;&lt;/td&gt;
      &lt;/tr&gt;
    % }
    &lt;/table&gt;
     
    &lt;p&gt;Enter a new motorcycle here (バイクを登録して下さい)&lt;/p&gt;
    &lt;p&gt;
      &lt;%= form_for '/' =&gt; (method =&gt; 'post') =&gt; begin %&gt;
% foreach (qw/type brand color/) {
        &lt;%= uc($_) %&gt;: &lt;%= input_tag $_, 'type' =&gt; 'text' %&gt;&lt;br /&gt;
% }
        &lt;%= submit_button 'Submit motorcycle' %&gt;
      &lt;% end %&gt;
    &lt;/p&gt;
  &lt;/body&gt;
&lt;/html&gt;</code></pre>

<p>スクリプト内部(__DATA__ 以下)のテンプレートで日本語文字列を使うような場合は、内部文字列として扱われるように use utf8; を追加しておくとよさそうです。</p>
]]></content:encoded>
	</item>
	<item rdf:about="http://www.akatsukinishisu.net/itazuragaki/perl/to_what_does_weaken_work.html">
		<title>weakenは何に対して効くか</title>
		<link>http://www.akatsukinishisu.net/itazuragaki/perl/to_what_does_weaken_work.html</link>
		<dc:subject>Perl</dc:subject>
		<dc:creator>北村曉</dc:creator>
		<dc:date>2010-11-25T13:37:00+09:00</dc:date>
		<trackback:ping rdf:resource="http://www.akatsukinishisu.net/itazuragaki/perl/to_what_does_weaken_work.tb"/>
		<description>Perlの[Scalar::Util] にある weaken について学んでいたところ、誤解していた点があったので覚え書き。以下のように、同じリファレンス値を持つ変数を2つ作り、片方だけを weaken することを考えます。use strict;use warnings;use feature qw(say);use Scalar::Util qw(weaken isweak);my ($a, $b);$a = $b = {};weaken $a;say "\$a = $a is ", isweak $a ? 'weak' : 'strong';say "\$b = $b is ", isweak $b ? 'weak' : 'strong';自分は、$aも$b...</description>
		<content:encoded><![CDATA[

<p>Perlの<a href="http://search.cpan.org/perldoc?Scalar::Util" title="Scalar::Util - search.cpan.org">Scalar::Util</a> にある <code>weaken</code> について学んでいたところ、誤解していた点があったので覚え書き。</p>

<p>以下のように、同じリファレンス値を持つ変数を2つ作り、片方だけを weaken することを考えます。</p>

<pre><code>use strict;
use warnings;
use feature qw(say);
use Scalar::Util qw(weaken isweak);

my ($a, $b);
$a = $b = {};
weaken $a;

say "\$a = $a is ", isweak $a ? 'weak' : 'strong';
say "\$b = $b is ", isweak $b ? 'weak' : 'strong';</code></pre>

<p>自分は、$aも$bもリファレンスとしては同じ値なのだから、$aをweakenすれば$bも弱くなる、という風に思っていたのですが、結果は以下の通りでした。</p>

<pre>$ perl a.pl
$a = HASH(0xc43ad8) is weak
$b = HASH(0xc43ad8) is strong</pre>

<p>リファレンスの値としては同じにも関わらず、$aのみが弱くなっています。</p>

<p>これはつまりどういうことかと考えたところ、weakenは<code>HASH(0xc43ad8)</code>というようなリファレンスとしての値に対して働くのではなく、リファレンスを格納する変数名(のようなもの)に対して働くものなのだ、と解釈すると納得が行きました。</p>

<p>※「変数名(のようなもの)」の例:</p>

<ul>
<li>スカラ変数であれば、 <code>$scalar</code></li>
<li>配列の要素であれば、 <code>$array[0]</code></li>
<li>ハッシュの要素であれば、 <code>$hash{key}</code></li>
<li>配列リファレンスの要素であれば、 <code>$array_ref-&gt;[0]</code></li>
<li>ハッシュリファレンスの要素であれば、 <code>$hash_ref-&gt;{key}</code></li>
</ul>

<p>引数の値ではなく変数名に対して働くということで言うと、weaken は my や local に似ているように思いました。</p>

<div class="divider">* * *</div>

<p>もう少し実際の利用例に近い形で言うと、例えば以下のように、互いに参照し合うオブジェクトがあり、一方の参照を弱くすることでブロック終端でオブジェクトの変数が開放されることを示す例を考えます。(コードは<a href="http://blog.livedoor.jp/dankogai/archives/51506391.html">404 Blog Not Found:perl - Data::Decycle で悪循環を断とう!</a>の記事にあったものを元にしてます)</p>

<pre><code>use strict;
use warnings;
use feature qw(say);
use Scalar::Util qw(weaken);

{
    package Foo;
    sub new { bless {}, $_[0] }
    sub DESTROY { warn "destroy $_[0]" }
}

{
    package main;
    my $parent = Foo-&gt;new;
    my $child = Foo-&gt;new;
    $parent-&gt;{child} = $child;
    $child-&gt;{parent} = $parent;
    weaken $child-&gt;{parent};
}

warn "end";

__END__
$ perl a.pl
destroy Foo=HASH(0xc43c70) at a.pl line 9.
destroy Foo=HASH(0xc9b510) at a.pl line 9.
end at a.pl line 21.</code></pre>

<p>で、このweakenの行において、<code>$child-&gt;{parent} = $parent</code> だからと言って <code>weaken $parent</code> としては意味がない、ということです。</p>

<div class="divider">* * *</div>

<p>なお、この辺りのことは<a href="http://search.cpan.org/perldoc?Scalar::Util" title="Scalar::Util - search.cpan.org">Scalar::UtilのPOD</a>にも以下のように説明されていました。</p>

<blockquote cite="http://search.cpan.org/perldoc?Scalar::Util" title="Scalar::Util - search.cpan.org">
<p>Note that if you take a copy of a scalar with a weakened reference, the copy will be a strong reference.</p>

<pre>    my $var;
    my $foo = \$var;
    weaken($foo);                       # Make $foo a weak reference
    my $bar = $foo;                     # $bar is now a strong reference</pre>
</blockquote>
]]></content:encoded>
	</item>
	<item rdf:about="http://www.akatsukinishisu.net/itazuragaki/perl/instmodsh.html">
		<title>インストールされているPerlモジュールはinstmodshで見れる</title>
		<link>http://www.akatsukinishisu.net/itazuragaki/perl/instmodsh.html</link>
		<dc:subject>Perl</dc:subject>
		<dc:creator>北村曉</dc:creator>
		<dc:date>2010-11-11T23:26:00+09:00</dc:date>
		<trackback:ping rdf:resource="http://www.akatsukinishisu.net/itazuragaki/perl/instmodsh.tb"/>
		<description>Perlで、インストールされているモジュールの一覧を取得するには ExtUtils::Installed を使うとよいという記事をよく見かけていたので、自分もよくそのようにしていました。[新しいPerlに今まで使ってたモジュールをまとめてインストールする - 酒日記 はてな支店][cpan コマンドでインストールしたモジュールを調べる - Yet Another Hackadelic]しかし本日、perlbrewでperl-5.12.2をイン...</description>
		<content:encoded><![CDATA[

<p>Perlで、インストールされているモジュールの一覧を取得するには ExtUtils::Installed を使うとよいという記事をよく見かけていたので、自分もよくそのようにしていました。</p>

<ul>
<li><a href="http://d.hatena.ne.jp/sfujiwara/20100517/1274081705">新しいPerlに今まで使ってたモジュールをまとめてインストールする - 酒日記 はてな支店</a></li>
<li><a href="http://d.hatena.ne.jp/ZIGOROu/20090416/1239863572">cpan コマンドでインストールしたモジュールを調べる - Yet Another Hackadelic</a></li>
</ul>

<p>しかし本日、perlbrewでperl-5.12.2をインストールした後、bin/ 配下に置かれるコマンドをなんとなく眺めていたところ、<a href="http://search.cpan.org/perldoc?instmodsh">instmodsh</a> というコマンドがあることに気付きました。これを使うと、</p>

<pre>$ instmodsh
Available commands are:
   l            - List all installed modules
   m &lt;module&gt;   - Select a module
   q            - Quit the program
cmd? l
Installed modules are:
   App::cpanminus
   HTML::Parser
   HTML::Tagset
   LWP
   Perl
   Time::HiRes
   URI
cmd? q
$</pre>

<p>という感じで、簡単なシェルインターフェースを介してインストールされたモジュールの一覧を得ることができます(上記はまだperlインストール直後なので出力が少ないですが)。</p>

<p>ソースを見たところ、こちらも内部では ExtUtils::Installed を使用しているようなのですが、それでも <code>perl -MExtUtils::Installed -le 'print for ExtUtils::Installed-&gt;new-&gt;modules'</code> といった、<em>ExtUtils::Installed</em>という長いモジュール名を2回も書くような onliner を思い出しつつ打つよりは楽でよいと思いました。</p>

<p>ちなみに、UIを介さずに直接一覧を出力したりファイルにリダイレクトさせたい場合には、以下のようにするとよいかと思います。</p>

<pre>$ echo -e "l\nq" | instmodsh &gt; instmod.log</pre>

<p>最初のメッセージやプロンプトを削りたいのなら、こんな感じで。</p>

<pre>$ echo -e "l\nq" | instmodsh | perl -ne 'next if 1 .. /^c/; print if /^\s/'</pre>

<p>検索した限りだとこの instmodsh について言及した日本語記事はあまり見かけない様子で、折角デフォルトでperlに入っているのに、知られていないのは勿体無いなと思ったのでした。</p>
]]></content:encoded>
	</item>
	<item rdf:about="http://www.akatsukinishisu.net/itazuragaki/perl/overwrite_method.html">
		<title>メソッドを局所的に上書きする</title>
		<link>http://www.akatsukinishisu.net/itazuragaki/perl/overwrite_method.html</link>
		<dc:subject>Perl</dc:subject>
		<dc:creator>北村曉</dc:creator>
		<dc:date>2010-06-17T11:32:00+09:00</dc:date>
		<trackback:ping rdf:resource="http://www.akatsukinishisu.net/itazuragaki/perl/overwrite_method.tb"/>
		<description>[知ってそうで意外と知られていないperlの小技 10選]という記事にある「モジュールのメソッドを上書きする」という項について考えてみました。記事にあるやり方では、本来のメソッド(コード)のリファレンスを保存型グロブによりメソッドを上書き上書きしたメソッドを実行保存していたコードリファレンスを更に上書きとなっていたのですが、こうするよりも、上書...</description>
		<content:encoded><![CDATA[

<p><a href="http://d.hatena.ne.jp/download_takeshi/20100610/1276178221" title="知ってそうで意外と知られていないperlの小技 10選 - ダウンロードたけし（寅年）の日記">知ってそうで意外と知られていないperlの小技 10選</a>という記事にある「モジュールのメソッドを上書きする」という項について考えてみました。記事にあるやり方では、</p>

<ol>
<li>本来のメソッド(コード)のリファレンスを保存</li>
<li>型グロブによりメソッドを上書き</li>
<li>上書きしたメソッドを実行</li>
<li>保存していたコードリファレンスを更に上書き</li>
</ol>

<p>となっていたのですが、こうするよりも、上書きが必要な箇所のみをブロック(<code>{ ... }</code>)で囲み、その中で<code>local</code>を使って上書きする方がよいのでは、と思ったのです。具体的に書くと以下の通り。</p>

<pre><code>use strict;
use warnings;

#----------

package Foo;
sub something { print "something original.\n" };

#----------

package main;
Foo-&gt;something();
{
    no warnings 'redefine';
    local *Foo::something = sub { print "something overwitten.\n" };
    Foo-&gt;something();
}
Foo-&gt;something();</code></pre>

<p>実行結果は以下の通り。</p>

<pre><samp>something original.
something overwitten.
something original.</samp></pre>

<p>こうすると本来のメソッドのリファレンスを保存する手間も省けるし、メソッド上書きと <code>no warnings 'redefine'</code> の効果の範囲も分かり易いのではないかと思います。</p>

<p>……ということを考えていたのですが、後日、<a href="http://d.hatena.ne.jp/hiratara/20100613/1276419609" title="Re: 知ってそうで意外と知られていないperlの小技 10選 - a geek born in Tomakomai">Re: 知ってそうで意外と知られていないperlの小技 10選</a>という別の記事で更に別のやり方が提示されていました。</p>

<blockquote cite="http://d.hatena.ne.jp/hiratara/20100613/1276419609" title="Re: 知ってそうで意外と知られていないperlの小技 10選 - a geek born in Tomakomai">
<p>事前にundefすると、 no warnings 'redefine' しなくとも警告は出ません。</p>
<pre><code>use strict;
use warnings;

sub do_something { ... }

undef &amp;do_something;
*do_something = sub { print "Implemented.\n" };

do_something;</code></pre>
</blockquote>

<p>サブルーチンを<code>undef</code>で未定義にできる、ということを知らなかったのでなるほどと思ったのですが、これをブロック内の<code>local</code>上書きでもできるだろうか、というところが気になり、試してみました。</p>

<pre><code>use strict;
use warnings;

#----------

package Foo;
sub something { print "something original.\n" };

#----------

package main;
Foo-&gt;something();
{
    undef &amp;Foo::something;
    local *Foo::something = sub { print "something overwitten.\n" };
    Foo-&gt;something();
}
Foo-&gt;something();</code></pre>

<p>結果は以下の通り。</p>

<pre><samp>something original.
something overwitten.
Undefined subroutine &amp;Foo::something called at b.pl line 18.</samp></pre>

<p>ブロック内であっても<code>undef</code>の効果はグローバルに及んでしまうので、本来のメソッドを保持できなくなっていました。</p>

<p>しかし<code>local</code>で宣言だけするなら、宣言した変数は未定義になることを思い出し、</p>

<pre><code>    local *Foo::something;
    *Foo::something = sub { print "something overwitten.\n" };</code></pre>

<p>とすればよいのでは、と思いつきました。これは一応意図通りに動いたのですが、型グロブでまとめて<code>local</code>宣言するということは、同じ名前を持つスカラ・配列・ハッシュ等の変数にも効果が及ぶということでもあります。以下のコードを試してみました。</p>

<pre><code>use strict;
use warnings;

#----------

package Foo;
sub something { print "something original.\n" };
our $something = 'SOME STRING';

#----------

package main;
Foo-&gt;something();
print $Foo::something, "\n";
{
    local *Foo::something;
    *Foo::something = sub { print "something overwitten.\n" };
    Foo-&gt;something();
    print $Foo::something, "\n";
}
Foo-&gt;something();
print $Foo::something, "\n";</code></pre>

<p>結果は以下の通り。</p>

<pre><samp>something original.
SOME STRING
something overwitten.
Use of uninitialized value $Foo::something in print at b.pl line 19.

something original.
SOME STRING</samp></pre>

<p>メソッドと同じ名前のスカラ変数(<code>$Foo::something</code>)もまとめて未定義にされていました。なので<code>local</code>宣言と上書きを分けて書くのは注意が必要かもしれません。</p>

<p>ちなみに、<code>local</code>宣言と同時にコードリファレンスを代入してやると、他の変数が上書きされるようなことにはなりませんでした。動作としてはやや不思議な気もしますが、これが一番問題の無い書き方のように思います。</p>

<pre><code>use strict;
use warnings;

#----------

package Foo;
sub something { print "something original.\n" };
our $something = 'SOME STRING';

#----------

package main;
Foo-&gt;something();
print $Foo::something, "\n";
{
    no warnings 'redefine';
    local *Foo::something = sub { print "something overwitten.\n" };
    Foo-&gt;something();
    print $Foo::something, "\n";
}
Foo-&gt;something();
print $Foo::something, "\n";</code></pre>

<p>結果は以下の通り。ブロック内でも<code>$Foo::something</code>の値は保持されていました。</p>

<pre><samp>something original.
SOME STRING
something overwitten.
SOME STRING
something original.
SOME STRING</samp></pre>

<p>関連:</p>

<ul>
<li><a href="http://b.hatena.ne.jp/kits/20100611#bookmark-22223975" title="はてなブックマーク - 徒栞 - 2010年6月11日">はてなブックマークコメントその1</a></li>
<li><a href="http://b.hatena.ne.jp/kits/20100614#bookmark-22290216" title="はてなブックマーク - 徒栞 - 2010年6月14日">はてなブックマークコメントその2</a></li>
</ul>
]]></content:encoded>
	</item>
</rdf:RDF>
