あらためてチャットサポートを構築する

Converse.js という XMPP の Web クライアントを見つけて「チャットサポートを構築する」の記事を書いたのは2014年初頭でした。Converse.js が公開されて1年めほどでバージョンは 0.7.2 でした。

2018年4月現在の Converse.js は 3.3.4 で、かなり進歩しています。情報もあちこちに出てきて、以前は苦労したことも現在では簡単にできるようになっていました。本家ページ以外に情報が散らばっていましたのでここにまとめてながら、あらためてチャットサポートを設置してみます。

PreBind

その前に、今回の構築には用いませんが、以前は私がよく理解できておらず適当に誤魔化していた PreBind について、簡潔に解説したページ PreBind: connettersi senza password がありましたので、紹介しておきます。

PHP のクラス XMPP Prebind for PHP をダウンロードしておき、次のようにインスタンス化します。

<?php 
include 'xmpp-prebind-php/lib/XmppPrebind.php';

$boshUrl = 'https://example.com:5280/bosh/';  // 環境に合わせて変更
$server = 'example.com';           // 環境に合わせて変更
$username = 'your_username';   // 環境に合わせて変更
$password = 'your_password';   // 環境に合わせて変更
$resource = rand(10000,99999); // ここでは5桁の数字。環境に合わせて変更

$xmppPrebind = new XmppPrebind($server, $boshUrl, $resource, false, false);
$xmppPrebind->connect($username, $password);
$xmppPrebind->auth();
$sessionInfo = $xmppPrebind->getSessionInfo(); // array containing sid, rid and jid

header('Content-Type: application/json');
echo json_encode($sessionInfo);

?>

これだけで動かしてみると分かりますが、sid, rid, jid の3つを JSON 形式で返すものです。

次に、Converse.js の初期化の際に、上のスクリプト名( prebind.php だとします)を prebind_url で指定します。

<?php
  $boshUrl = 'https://example.com:5280/bosh/';  // 環境に合わせて変更
  $server = 'example.com';      // 環境に合わせて変更
  $username = 'your_username';  // 環境に合わせて変更
  $prebindUrl = 'prebind.php';  // 上のスクリプトの URL
?>
<html>
  <head>
    ...
    <link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/inverse.min.css" />
    <script src="https://cdn.conversejs.org/dist/converse.min.js"></script>
    ...
  </head>
  <body>
     ...
    <script>
      converse.initialize({
        i18n: 'ja',
        locales_url: 'https://cdn.conversejs.org/locale/{{{locale}}}/LC_MESSAGES/converse.json',
        authentication: 'prebind',
        bosh_service_url: '<?php echo $boshUrl; ?>', 
        keepalive: true,
        jid: '<?php echo $username."@".$server; ?>',
        prebind_url: '<?php echo $prebindUrl; ?>',
        prebind: true,
        ...
      });
    </script>
  </body>
</html>

この HTML は誰にも見られることになりますが、パスワードは事前接続にのみ用いられているので、ここに書かずに済むというわけです。

チャットサポートの構築

XMPP サーバーで匿名接続を利用できる場合、Converse.js の初期化時に authentication: 'anonymous' とすることで、実は上述の PreBind はまったく使わずに済みます。

以下、この匿名接続を使ってチャットサポートを組み立てます。

  • 客側は Converse.js で匿名(一時的なJIDを使う)とする。
  • 窓口側のJID(たとえば support@example.com) は共有名簿として匿名接続時に与えられる。
  • 客側の Converse.js は自動的に窓口側JIDを呼び出しチャット窓を開く。

という流れです。

サーバー側設定

BOSH または Websocket

前述の PreBind でもそうでしたが、BOSH(または Websocket)を利用しますので、XMPP サーバーに付属のそれらの機能を有効にしておきます。ejabberd の場合、ejabberd.yml は次のようになります。

listen:
  ...
  -
    port: 5280
    ip: "::"
    module: ejabberd_http
    request_handlers:
      "/ws": ejabberd_http_ws
      "/bosh": mod_bosh
    http_bind: true
    register: true
    tls: true
  ...
modules:
  ...
  mod_bosh: {}
  ...

匿名サーバー

通常クライアントがサーバーに接続する場合は、事前に作成しておいた user@example.com という形をした JID とパスワードが必要になります。匿名サーバーは、そのサーバー名だけを指定して接続を試み、@ より前のユーザー名を乱数のようにそのつど生成して接続します。

サーバーアプリケーション ejabberd の場合、ejabberd.yml に次のように設定して SASL 匿名サーバー (anonymous.example.com という名前だとします) を設定します。

hosts:
  - "example.com"
  - "anonymous.example.com"
  ...
host_config:
  "anonymous.example.com":
    auth_method: [anonymous]
    anonymous_protocol: sasl_anon

なお今回は特に関係ありませんが、匿名サーバーで接続するユーザーについては、悪用を防ぐため権限を絞っておくのが望ましいでしょう。たとえば、別のサーバーとの通信の禁止、MUC 談話室や PubSub ノードの作成の禁止、などです。

窓口側のJID

窓口側のJID(例: support@example.com) の作成は、通常どおり行います。

共有名簿(shared roster)

匿名サーバーの場合、接続のたびにアカウントが新たに一時的に生成されるため、その JID には相手先名簿がありません。そこで、共有名簿(shared roster)という機能を使うことにします。

まず ejabberd の設定ファイル ejabberd.yml でこの機能を有効にしておきます。

modules:
  ...
  mod_shared_roster: {}
  ...

ejabberd のウェブ管理画面の「バーチャルホスト -> anonymous.example.com -> 共有名簿グループ」の画面で、まずひとつのグループを作成します。たとえば

  • 名前: support
  • 説明: サポート窓口
  • メンバー: support@example.com
  • 表示グループ: (空欄)

のようにします。ここで support@example.com は、窓口側(問い合わせを受ける側)の JID です。

さらにもうひとつグループを作成します。

  • 名前: all
  • 説明: 全ユーザー
  • メンバー: @all@
  • 表示グループ: support

ここで @all@ は、「全ユーザー」を意味します。

これで、「anonymous.example.com の全ユーザーの名簿に support グループのメンバー(ここでは support@example.com のみ)を自動的にセットする」ことができました。

Converse.js の設定

チャットウィンドウを設置する Web ページで、Converse.js を読み込むようにいくつかの行を書き加えます。Converse.js そのものを同じサイトに置いてもいいですし、CDN から読み込むようにもできます。

<head>
    ...
    <link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/converse.min.css" />
    <script src="https://cdn.conversejs.org/dist/converse.min.js"></script>
    ...
</head>

それから、パラメータとともに Converse.js を初期化することで、そのページにチャットウィンドウを設置します。基本は

converse.initialize({
        websocket_url: 'wss://example.com:5280/ws/',
        authentication: 'anonymous',
        jid: 'anonymous.example.com',
        auto_login: true,
})

です。ここでは BOSH ではなく WebSocket を使う場合です。匿名接続の場合 jid はサーバー名のみにします。自動ログインでサーバーに接続するのですが、このままでは相手先とのチャットを開くところはできません。

自動で相手先とのチャットを開く

この情報は本家ではないところにありました。Converse opening a chat from API の回答で Converse.js の作者がプラグインを紹介しています。

converse.plugins.add('chatsopen', {
      initialize: function() {
        var _converse = this._converse;
        Promise.all([
            _converse.api.waitUntil('rosterContactsFetched'),
            _converse.api.waitUntil('chatBoxesFetched')
        ]).then(function() {
          _converse.api.chats.open('support@example.com');
        });
      }
    });

初期化時にこれを利用するようにします。

whitelisted_plugins: ['chatsopen'],

コントロールボックスは全部隠してしまうこともできます。

blacklisted_plugins: ['converse-controlbox'],

まとめ

以上をまとめて(ついでに他のパラメータも追加して)、チャットウィンドウを設置する Web ページまるごとの例です。

<html>
<head>
    <meta charset="utf-8"/>
    <title>チャットサポート</title>
    <link type="text/css" rel="stylesheet" media="screen" href="https://cdn.conversejs.org/css/converse.min.css" />
    <script src="https://cdn.conversejs.org/dist/converse.min.js"></script>
</head>
<body>
<h1>チャットサポートのページ</h1>
<p>右下の窓で話しかけてください。</p>
</body>
<script>
    converse.plugins.add('chatsopen', {
      initialize: function() {
        var _converse = this._converse;
        Promise.all([
            _converse.api.waitUntil('rosterContactsFetched'),
            _converse.api.waitUntil('chatBoxesFetched')
        ]).then(function() {
          _converse.api.chats.open('support@example.com');
        });
      }
    });

    converse.initialize({
        i18n: 'ja',
        locales_url: 'https://cdn.conversejs.org/locale/{{{locale}}}/LC_MESSAGES/converse.json',
        authentication: 'anonymous',
        websocket_url: 'wss://example.com:5280/ws/',
        auto_away: 300,
        auto_reconnect: true,
        keep_alive: true,
        jid: 'anonymous.example.com',
        auto_login: true,
        allow_logout: false,
        allow_contact_removal: false,
        allow_contact_requests: false,
        allow_muc: false,
        allow_otr: false,
        allow_registration: false,
        blacklisted_plugins: [
            'converse-bookmarks',
            'converse-controlbox',
            'converse-mam',
            'converse-muc',
            'converse-notification',
            'converse-otr',
            'converse-register'
        ],
        whitelisted_plugins: ['chatsopen'],
        forward_messages: false,
        message_carbons: false,
        message_archiving: 'never',
        use_vcards: true,
        view_mode: 'overlayed',
        visible_toolbar_buttons: {
            call: false,
            clear: false,
            emoji: true
        }
    });
</script>
</html>

実際に設置してみたのが次です(サーバー名など変更)。

醤油差し

多くの人に経験があると思うのですが、醤油差しの液だれは地味にストレスです。これまでに100均のものをはじめいくつも使ってきましたが、どうもしっくりきません。何かいい知恵はないかとネットで検索してみると出るわ出るわ……。皆さん同じような思いをされているのでしょう。

そういうページで紹介されているものは案外種類が少なく、ベスト10となると多少順位は変わっても同じような顔ぶれがランクインしています。

最後に使っていた安物の醤油差しは差し口からの液だれなのか蓋と本体の継ぎ目からの漏れなのか判然としなかったのですが、周囲の汚れることおびただしかったのです。そこで、まず頭で考える私にはひとつこれだけはと思っている点がありました。注ぐ際に醤油が蓋と本体の継ぎ目をまたがなければ、後者の問題は起こり得ません。あとは注ぎ口の形状にのみ注意すればいいのです。

そうすると、あちこちで紹介されている白山陶器 G型しょうゆさし 大 白磁が候補に挙がりましたが、評判をじっくり見ていくと少数とはいえ液だれがあるというのが見つかります。陶製だと精度が出にくいのでしょうか、個体差があるのではないかと思われます。

結局、陶器より精度のよさそうなガラス製(残量もわかりやすいですし)の「iwaki クラフトライン しょうゆ差し 100ml K5023-SV」に決めました。しばらく使ってみましたが、注ぎ口からの液だれはまったくありません。もし蓋のパッキンが劣化して密閉性が多少悪くなっても醤油はそこを通過しないのでぜんぜん問題はありません。もう少し値段が安かったら言うことはありません。

さて、見た目が面白いのでスウちゃん(仮名・9歳)に
父「こっち(本体側)とこっち(注ぎ口側)の醤油の高さは同じになるんだよ」
などと話をしていました。
父「傾けても高さは同じになるよ」
スウ「違うよ」
父「えっ」
スウ「違うよ」
父「……」
よく見ると確かに。注ぎ口のほうは水平ですらありません。うーむ。「それは“表面張力”と言ってだな、」と言いかけましたが、残念ながらスウちゃんはそんなところまで興味はないのでした。もし入試にこんな問題があるとすれば、但し書きがないと「出題ミス」と揚げ足を取られることになりそうです。

Rhythmbox を DLNA クライアントとして使う

何を今さらというような内容かもしれませんが、ちょっと苦労したのでメモしておきます。

やりたいことは以前書いた「リモートに置いてある音楽ファイルをローカルPCのスピーカーで鳴らす」と同じです。あれから時間が経ってまたまた環境がずいぶん変わってしまいました。現在は宅内のリモートマシンで DLNAサーバー(Debian の minidlna パッケージ)を動かしており、それから手元の PC で何らかの手段で音楽を聴きたいのです。

手元の PC (OS は Debian testing です)にはインターネットラジオを聴くのに Rhythmbox がインストールされていて(Debian パッケージで言うと rhythmbox と rhythmbox-plugins)、これで DLNA を使えればいい訳で、検索してみると Ubuntu 情報ですが、パッケージ grilo-plugins-0.3 と libgrilo-0.3-0 を追加インストールすれば左欄に DLNA サーバーが現れるかその一番下の + でサーバーが見つかるようになる……はずなのですが、ぜんぜん反応しません。

なかなか手がかりがなく困り果てていたのですが、ふと

(rhythmbox:16045): Grilo-WARNING **: [dleyna] grl-dleyna-servers-manager.c:138: Unable to fetch the list of available servers: GDBus.Error:org.freedesktop.DBus.Error.ServiceUnknown: The name com.intel.dleyna-server was not provided by any .service files

の警告(エラーではないのであまり気にしていなかった)の中のキーワードから、dleyna-server という Debian のパッケージを追加したら、無事に左欄の「共有」のところに DLNA サーバーが現れました。

結局、必要なのは

  • rhythmbox
  • rhythmbox-plugins

  • grilo-plugins-0.3

のほかに

  • dleyna-server

でした(依存関係でそのほかいくつか)。

しかし、dleyna-server に言及している情報にほとんど行き当たらなかったのはどうしてだろう……。

薪ストーブでブルーベリーパイ

スウちゃん(仮名、9歳)が突然「リンゴない?」と聞いてきました。数日前に買ってきた冷凍パイシートのパッケージの裏に書いてあるアップルパイの作り方を見ていたのです。「そんな急に言われてもないよ」と答えるしかありませんが、夏に採ったブルーベリーがまだ冷凍庫に残っていたことを思い出し、これでやってみることにしました。

材料

  • 冷凍パイシート 4枚入
  • ブルーベリー 適量(100gくらい?)
  • 砂糖 適量(30gくらい)

小鍋(相変わらず鉄鍋でも気にしないことにします)にザラザラっと入れたので正確にはわかりませんが 100gくらいのブルーベリー、それを見て砂糖も適当に。薪ストーブの天板に載せるとすぐ水がどんどん出てきます。とろみが出るまで1時間ちかく煮詰めました。

1枚のパイシートにブルーベリーのジャムを載せ、その上に短冊状に切ったもう1枚分のパイシートを載せました。パッケージには4枚入だったので、これが2組できます。

焼くのも薪ストーブを使います。うちの薪ストーブの火室は幅18インチ、奥行き21½インチとやたら大きく、またガラス窓の前面以外は1¼インチ厚の耐火レンガで囲われていて、ちょうどピザ窯みたいなものなのです。朝から焚いているのでしっかり熱くなっています。火室内の温度を見極めるのが難しいのですが、暖房としては弱すぎるくらい温度が下がってきた頃がちょうどよくなります。炎が上がっているのではもちろんだめで、ジャムを煮詰めている後半からだんだん火を絞り、残った熾は奥の方に押しやって手前を灰だけにして(そうしないと底が熱くなりすぎ、上面が焼ける前に裏面が焦げてしまいます)五徳を入れ、そこにパイ生地を載せたスキレットを置きます。

数分で焼き上がります。するとスウちゃんはさっさとそれを持ってお友達のところへ出かけていってしまいました。出来上がりの味はわかりませんが、鍋に残ったジャムを舐めてみたらちょっと甘すぎたかもしれません。今回は冷凍のパイシートを買ってきていたので、たいへん楽でした。

薪ストーブで八朔マーマレード

家の裏にある八朔がたくさん実をつけたので、マーマレードを作ることにしました。肥料どころか普段から何一つ手をかけない放置状態ですから、掛け値なしの無農薬です。

「焦げつかない程度に火を強くして短時間で」らしいですが、量が多いと結局は時間もかかるし何かと大変なので、うちでは薪ストーブで煮込みます。それに金属でなくホーロー鍋のほうがいいらしいですが、それも気にしないことにします。

材料

  • 八朔 2000g
  • 白砂糖 800g

作業1日め

今年一番の雪の後にソリを引いて収穫に行きました。積もった雪のおかげで実に手が届きました。でもこの雪で大枝が折れてしまいました。来年以降はどうなることやら。

八朔をきれいに洗い、4分の1にカットして、外皮と果肉に分けます。

外皮は、千切り(できるだけ薄くスライス)します。今回はスウちゃん(仮名、9歳)が外皮をぜんぶ包丁でスライスしました。けっこう固いし大丈夫なのかと思いましたが割と上手に薄く切り、いつの間にかこんなことも難なくこなせるようになったんだなあと感心しきり。

果肉は、スウちゃんが外皮を切っている間に父がひたすら薄皮剥き。本当の果肉と、薄皮・種を別にして保存しておきます。

2人とも手が忙しいだけなので、たくさん色々な話ができました。普段は宿題などやらなければならないことや楽しいことに気持ちがいってしまうので、じっくり話す機会が実は減っていたのだなと逆に気づかされました。

外皮は水を換えながら揉み洗いを数回、その後たっぷりの水に浸しておきます。そんな感じで1時間ほどで作業終了。

作業2日め

都合で1日あけたので、丸2日近くも水に浸しておいたことになります。途中で何度か水を換えています。

小鍋で、別にしておいた薄皮・種を少量の水で煮はじめます。2時間ほどでどろどろになるのでザルでこし、その汁を後で使います。

水に浸していた外皮を、水切りして鍋に入れ、500ccくらいの水[1]で1時間ほど煮ます。はじめは全部が水に浸らないのでときどきかき混ぜます。

果肉ぜんぶと砂糖の半量、小鍋でできた汁(増粘剤となるペクチン)を加え、さらに1時間ほど煮ます。瓶の煮沸に湯をたくさん使うので、八朔を煮ている鍋の脇でヤカンなどで沸かしておきます。

八朔を煮ている間に瓶の用意をします。きれいに洗って大きな鍋で煮沸します。大鍋は薪ストーブの上に載せにくいので、これはガスコンロで行います。

さて八朔に戻って、残りの砂糖を加え、水分が少なくなり粘りが出るまで煮ます。焦げつかないように何度もかき混ぜます。ヤカンの湯は煮沸に使ってしまいましたが最後の瓶詰めにもたくさんの湯を使うので、またヤカンで沸かしておきます。

最後は、長期保存のための瓶詰めです。きれいになった瓶にマーマレードを入れていきます。瓶の口とネジの部分をきれいに拭いてから蓋を載せ、ネジ蓋を軽く締めます(蓋の丸い平らな部分と、周囲のネジの部分が分離しているタイプです)。このときはまだ強く締めません。カゴに入れて煮立ったお湯に瓶の下半分を浸し、10分ほど瓶ごと茹でます。これは大鍋であることと瞬発的な火力がほしいのでガスコンロで行います。

充分熱くなったらそこから瓶を引き上げながらネジ蓋を強く締めます。だんだん冷めてくると中の圧力が下がり、「ペコッ」と音がして蓋の中央が凹みます。密封できている証拠です。これで軽く1年は保存できます。半パイント瓶に11本のマーマレードが完成しました。

今回はちょっと手を抜いたこともあって、苦味がやや強くなりました。それはそれで美味しいですけどね。外皮の内側の白い部分を包丁を入れてできるだけ取り除く、外皮を煮る際のはじめの煮汁を捨てる、薄皮・種は使わない、そして砂糖を多めになどすれば、もうちょっと苦味の少ない甘いマーマレードができるかもしれません。

  1. 結局、最後は煮詰めるので水の量は適当です。

昨年のクリスマスプレゼント「スナップサーキット Snap Circuits Snaptricity」

昨年のクリスマスプレゼントを振り返るシリーズ。スウちゃん(仮名・当時8歳)が受け取ったのは「スナップサーキット Snap Circuits Snaptricity」でした。

日本での情報が多く、たぶん簡単に購入できそうなのは SC-100 か SC-300 です。それらのマニュアルを PDF で見ることができるので、よく見てみました。するとトランジスタや、さらにはブラックボックス化している IC までが部品にあることがわかりました。そもそも電気回路の初歩の初歩も知らない子にはレベルが高すぎるし、ブラックボックスが含まれるのはいただけません。作例の数が 100 や 300 となってはいますが、そういうものを除くとぐっと少なくなってしまいます。

Webページを見てみると、基本モデルセットだけでも実はたくさんあることがわかりました。そのうち Snaptricity (SCBE75) は次のようです。

  • 部品は豆電球、スイッチ、モーター、メーターなどで、入門用にはぴったり。トランジスタ・抵抗・コンデンサなどはないが SC-100 にはない電磁石がある。
  • 日本では入手しにくそうだが、アメリカの Amazon.com で購入すれば、送料を入れてもけっこう安い。
  • マニュアルが充実。SCBE75 のマニュアルは作例ごとに Educational Corner という解説がついていて、これがちょっとした教科書並みにいい。
  • いざとなれば(つまりスウちゃんがぐっとのめり込んできたら)追加パーツを購入すればいいさ。あるいは Project Labs EP130 というのもいい[1]

抵抗くらいは欲しい気がしますが、このキットでオームの法則の実験例では豆電球やモーターを抵抗として使っています。確かにそれでいいですね。

マニュアルは英語ですがとても丁寧な感じです。でも英語だとスウちゃんはきっと見向きもしないので、父が翻訳版を作ることにしました。図がメインなのでそれはオリジナルを見てもらって、文章のところだけ。作例も75ほどなのでなんとかなるでしょう。PDF のマニュアルが Web ページから見ることができるので、実物が届く前からすこしづつ訳し始めました。

スウちゃんは、まずマニュアルの作例を見ながら組んでみました。プロペラが飛び上がるのが単純に面白いらしく、ゲラゲラ笑いながら何度もやっていました。そのうちマニュアルを離れ、とにかく電池の両端をつなぐ路ができればいいということに気づき、その間に電球やらスイッチやらを入れながら適当に組んでやってみていました。横から口を出してあまり勉強ぽく言ってもつまらなくなるので放っていますが、ときどき思い出したように遊んでいます。

作りはしっかりしていて、スナップもなかなか勝手のいいものです。何度も書きますが、マニュアルの充実ぶりはたいへんすばらしいものです。惜しむらくは日本語でないこと。訳をプリントして渡してみたものの、やはりはじめから自分で読めるものがあるともっと入り込みやすかったでしょう。日本で「電脳サーキット」という名前で売られているものには日本語解説書が付くようです(残念ながら Snaptricity の日本版はないようです)。

もうひとつ残念だったのは、3つの電球の抵抗値(明るさ)がかなり違うことです。もうちょっと揃っていないと、簡単な「直列つなぎと並列つなぎ」の違いも実感しにくいと思いました。

いまのスウちゃんには特に磁力のところは、マニュアルどおりに組んでやってはみたものの、あまりピンときていない模様です。数年前のプレゼント Zome toolと同じく、もう何年か経ってからでも遊び直してほしいものです。

  1. すごく昔、学研マイキット(検索してみたら「システム7」というセット)というそっくりなもので父は遊んでいました。

消しゴムを使うな

小学校3年生のスウちゃん(仮名)は夏休みに入りました。

1学期のあいだ、テストがいくつもありました。宿題のプリントもそれはそれはたくさんありました。どれも採点されて返されます。スウちゃんはどうしてもうっかりミスが多く、なかなか100点が取れません。そういうたくさんのプリントやテストを持ち帰って見せてくれるのですが……。

間違えたところも解答が消しゴムで消されて書き直され、丸が付けられています。先生がそのようにしているのです。「ぜんぶ丸になるまで」という指導のようです。担任の先生は毎年変わっているのですが、これまでのどの先生もこのやり方でした。流行りというか、そういう指導の指導でもあるのでしょうか。

プリントを持ち帰ったスウちゃんに「ここ、はじめはどういうふうに間違ったの?」と聞いても「わからない。忘れた」というのがほとんどで、何をどのように間違えたかがわからないのです。この「間違った答を消しゴムで消して丸になるまで」の効果がさっぱりわかりません。

授業中にとるノートも、消しゴムを使ってきれいに仕上げることが徹底して指導されているようです。まあ、まだ小学校低学年ですから「ノートの書き方」そのものを教えなければならないこともわかるのですが。

しかし子どもは、短絡的にしか理解していません。

先日、スウちゃんは宿題の漢字練習をやっていました。ひとつの漢字を1行びっしり書き、漢字ドリル2ページ分、つまり20個ほどの漢字を練習するというものです。そのやり方自体がいいかどうかはここではとやかく言わないことにします。

スウちゃんは最後近くまでいったところで、そのびっしり書いたほとんど丸2ページ分を消しゴムで消し始めました。私がびっくりして「どうしたの?」と聞くと、3文字めか4文字めの漢字を飛ばしていたことに気がついたのでやり直すというのです。「いや、もういいよ。飛ばしていた字を最後に1行やればいいよ」と私が言っても、「そんなんじゃだめなんだよ。先生がちゃんとぜんぶ消して書き直しなさいって言うもん」と、泣きそうになりながら頑なに消しゴムをかけ続けます。時間はものすごく無駄だし消しゴムのかすもひどいことになるし、漢字練習の意味も何もありません。それでも先生の言うことは絶対のようです。本当に先生がここまでのことを要求しているかどうかは不明ですが、普段のノートやプリントの指導からして、子どもがこのように理解していても不思議はありません。

***

スウちゃんのことを離れて、自分のことを書きます。

もう何十年も前、私が子どもだったころ、父にノートの使い方を教わったことを思い出しました。父は高校の教師でしたから、多くの経験からそれを確立していたのだと思います。

美しさにこだわらない
本でもないし人に見せるものでもない。自分のためのもの。
詰め込みすぎない
とはいえギュウギュウに書いても、自分ですら読み返せない。訂正(後述のように消しゴムはなるべく使わない)したりコメントを追記したりできる余裕を持たせる。
2本のラインを引く
ノートのページを番号欄、本体、備考欄に3分割して使う。これをうまく説明する参考にできるものはないかと検索してみたら、「東大合格生が小学生だったときのノート」というものを見つけました。「約束5」がまさに父が教えてくれたことそのものです。
消しゴムはなるべく使わない
途中式、間違いにも意味がある。備考欄を活用すれば消しゴムはあまり使わずに済むはず。
定規はなるべく使わない
定規を使わずに直線をきれいに描く練習はあらかじめしておく。分数や筆算のときはもちろん、数直線やグラフのときにも不要。

先ほどの「東大合格生が小学生だったときのノート」の紹介PDFを見てみると、ここに挙げたほかの項目も実にそっくりという気がします。先駆けること数十年、わが父ながら感服します。

私が父に教わったのは小学校の高学年のころだったと記憶しています。自分でも非常に効果的だと実感したので、その後の中学・高校もしっかり踏襲していました。東大にこそ進まなかったけれどそれなりの成果にもつながったのだろうと、いま振り返ってみても思います。

***

スウちゃんはいま夏休みの宿題(ドリル)に取り組んでいます。採点は親がやることになっています。やっぱりうっかりミスが多いスウちゃんに「間違ったところは消さないで、その脇にもう一度考え直してから答を書いてごらん」と言って採点したものを渡しても、もう染み込んでしまった習慣で、見直しもそこそこにまず最初に消しゴムで消してしまうのでした。先生の威厳と信頼を損ねないように気をつけながら、なんとかこの悪癖を止めさせたいものです。