MTのプラグインでFizzBuzz(笑)

何やら巷で「FizzBuzz問題」が流行っているようです。

参考:

Junnamaさんの記事を見てついカッとなって(笑)、FizzBuzz問題の結果を出力するためのプラグインを作ってしまいました。

1.FizzBuzz問題とは?

「FizzBuzz」は英語圏の遊びで、以下の決まりを守りつつ、数字を順番に数えてくものです。

  • 3の倍数の時は「Fizz」と言う
  • 5の倍数の時は「Buzz」と言う
  • 3の倍数かつ5の倍数の時(つまり15の倍数の時)は「FizzBuzz」と言う
  • それ以外の時は数字をそのまま言う

そして、この問題をプラグラムとして書けるかどうかで、プログラマー志願者をふるい落とすのが、「FizzBuzz問題」です。

2.FizzBuzzプラグイン

この問題をMTのプラグインにすると、以下のようになりました。
Movable Type 4以降で動作するはずです。

package MT::Plugin::FizzBuzz;
use base 'MT::Plugin';

use strict;

use MT;
use MT::Template::Context;
use MT::Plugin;

my $plugin = MT::Plugin::FizzBuzz->new({
    id => 'fizzbuzz',
    name => 'Fizz Buzz',
    version => '1.00',
    author_name => "<MT_TRANS phrase=\"Hajime Fujimoto\">",
    author_link => 'http://www.h-fj.com/blog/',
    description => "<MT_TRANS phrase=\"Fizz Buzz plugin.\">",
});
MT->add_plugin($plugin);

sub init_registry
{
    my $plugin = shift;
    $plugin->registry({
        tags => {
            function => {
                'FizzBuzz' => \&fizz_buzz,
            },
        },
    });
    
}

sub fizz_buzz {
    my ($ctx, $args) = @_;

    my $num = $args->{number};
    my $out = '';
    $out .= 'Fizz' if ($num % 3 == 0);
    $out .= 'Buzz' if ($num % 5 == 0);
    $out = $num if (!$out);
    $out;
}

1;

「<$MTFizzBuzz number="数字"$>」のようにすると、その数字の時に言うべき言葉が出力されます。
例えば、以下のように使うことができます。

<ul>
<MTFor from="1" to="30">
<li><MTVar name="__counter__"> = <MTFizzBuzz number="$__counter__"></li>
</MTFor>
</ul>

3.テンプレートタグでやってみる

ちなみに、Movable Type 4.1/MTOSでは、標準のテンプレータグだけで、FizzBuzzを表示することができます。
Junnamaさんも作っていましたが、私も作ってみました。
以下のようにタグを組むと、上のプラグインと同じ結果を得ることができます。

<ul>
<MTFor from="1" to="30">
<MTSetVar name="fizz" value="$__counter__"> 
<MTSetVar name="fizz" op="%" value="3">
<MTSetVar name="buzz" value="$__counter__"> 
<MTSetVar name="buzz" op="%" value="5">
<MTSetVar name="fizzbuzz" value="$__counter__"> 
<MTSetVar name="fizzbuzz" op="%" value="15">
<li>
<MTGetVar name="__counter__"> =
<MTIf name="fizzbuzz" eq="0">
FizzBuzz
<MTElse name="fizz" eq="0">
Fizz
<MTElse name="buzz" eq="0">
Buzz
<MTElse>
<MTGetVar name="__counter__">
</MTIf>
</li>
</MTFor>
</ul>