sci

最果て風呂

mto を deno で実装してみる

Node.js に代わる JavaScript 実行環境である deno が言及されることが多くなり、自分も興味があったので使ってみることにしました。

素材はいつものように mto。Node.js で使う JavaScript 版を下地としてスタート。deno は JavaScript がそのまま使え、また TypeScript に対応(というかこっちが本命?)しているので、変更点はこの部分に関わるところになるのでしょうか。

変数の定義

JavaScript では 変数をすべて var で定義していましたが、TypeScript ではできるだけ constlet を使うのが望ましいとのことです。定数は const にして、変数は let で修飾するようにしました。

var kanajisyo =const kanajisyo:string =var dicarr = [];let dicarr:string[][] = new Array(); のようにちょっと面倒になりましたね。

環境への入力出力

環境変数を取得するには、Node.js では process.env["hoge"] としている部分を Deno.env.get("hoge") のように修正。これは実装の違いだから仕方ないけれど、似ているのでわかりやすいです。

出力をするには、Node.js では process.stdout.write(hoge); としている部分を Deno.stdout.write(new TextEncoder().encode(hoge)); のように修正。なんか長くなりました。

ファイルの読み込み

Node.js では require('fs') としてライブラリを読み込んでから fs.readFileSync(ifile, 'utf8') で読み込みをしていました。deno では Deno.readTextFileSync(ifile) のみで良かった。テキストファイルのデフォルトを "UTF-8" で想定しているのか、読み込み時にファイルエンコードを指定する必要がありません。

同期・非同期という馴染のない思想があり、deno では非同期処理が基本となるようです。ファイルの読み込みに関しても、Deno.readTextFile(ifile) は非同期処理に。自分はよくわからないので順次処理をしてもらいたいので Sync 付きの方を使いました。

実行時のオプション

deno では外部環境との接触をデフォルトで否としているので、プログラムを実行する際には --allow-env --allow-read のように明示的に指定してやらないといけません。自分がひとりで使うには面倒なので、設定で有効にしちゃうかも。

感想

意外とすんなりと修正することができました。型の指定が面倒なのと同期・非同期の思想がわかっていないので、使い続けるならその辺を勉強しないといけないなぁ。

現状では問題があって、大きいファイルを変換させると途中までしか出力してくれないのでした。

追記その1 (2021.12.12)

入力ファイルの途中までしか処理してくれない件について。16KB 制限があるようで、ネットでもそれに関する issue が本家で 1 つ見つかりました。が、自分の問題は解決していません。

追記その2 (2022.01.07)

変換した文字列を出力するのに console.log(); では出力の最後に改行が入ってしまうため、Deno.stdout.write(new TextEncoder().encode()); を使うようにしていました。しかしこれでは長文を変換させると 16KB 程で出力が切れてしまう問題があったのです。

いままで Deno.readTextFileSync が悪いのかなぁと思っていたのですが、Deno.stdout.write が悪いのだと気がつきました。きっかけは辞書の大きさを調べてみようとしたこと。辞書ファイルは 200KB を越えているのですが、処理は最後まできちんと行なわれて完全な辞書が生成されていたのです。

ファイルの読み込み部分は悪くないことがわかり、出力の方を疑いはじめると簡単に答えが見つかりました。Deno.stdout.writeSync() を使うと期待通りの動作になりました。write も非同期処理なんですね。