NANOChatのMENTA化、その3

遅々として進みませんが。 JSONを使って読み書きをすることにしたのですが。 そもそも、アプリケーションの設定をどう呼ぶか、とか、テンプレートからJSON等のモジュールをどうやって使うか、とかいう根本的なところで悪戦苦闘してました。 menta.cgiには、「あなたのアプリの設定」とされている部分があるのですが、それをどのようにして呼ぶのかをソースを見ながら試してみました。 どのように呼ぶのを想定しているのかは不明ですが、とりあえずの解決策としては、

1
? my $self = MENTA->config->{application}

として、$selfに入れてから使うようにしました。 設定を以下のようにした場合、

1
2
3
4
5
    # あなたのアプリの設定
application => {
limit => 30,
member_filename => 'member.cgi',
},

それぞれ以下のようにして使えます。

1
2
$self->{limit}           # 30
$self->{member_filename} # member.cgi

で、JSON等のモジュールをどうやって使うかですが。 とりあえず安直に考えて、

1
? use JSON

としてから、関数形式で使うことにしました。 しかし、ここで一つ罠がありました。 JSONで使おうとした関数は「to_json」と「from_json」なのですが、単純に書いてしまうと、それぞれ、「to.pl」と「from.pl」というプラグインを探しにいってしまうのです。 まあ、関数をそのまま呼び出せないのであれば、パッケージ名をつけてやればよい、ということで、それぞれ「JSON::to_json」と「JSON::from_json」というように呼び出して解決できました。 解決したので、それはそれでよかったのですが、なんとなくプラグイン化してみました。 関数名を「json_to」と「json_from」という名前にして、「json.pl」を呼び出すようにしました。 プラグインというには微妙ですが、とりあえず機能的には問題ないということで。

app/controller/nanochat/enter.mt

1
2
3
4
5
6
?= render('nanochat/header.mt', '名前を教えてほしいの。')
?= render('nanochat/member.mt')
<div class="nano">
<p>工事中なの。</p>
</div>
?= render('nanochat/footer.mt')

app/controller/nanochat/member.mt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
? my $self = MENTA->config->{application}
? my $datafile = MENTA->data_dir() . $self->{member_filename}
? my $members = json_from(file_read($datafile))
? my @new_members
<div class="nano">
<p>今は、
? foreach my $member (sort {$b->{now} <=> $a->{now}} @{$members}) { # 更新時間の新しい順でソート
?     if (time - $member->{now} < $self->{limit} * 60) { # タイムアウトしていない場合
?         push @new_members, $member
<strong class="name"><?= $member->{name} ?></strong> さんと
?     }
? }
<strong class="name">なの</strong><?= @new_members ? " " : " だけ" ?>がいるの。</p>
</div>
? file_write($datafile, json_to(\@new_members))

plugins/json.pl

1
2
3
4
5
6
7
package MENTA::Plugin::JSON;
use MENTA::Plugin;
# JSONを使う用
use JSON;
sub json_to { to_json(shift) }
sub json_from { from_json(shift) }
1;
comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy