2025-05-15

『灯台へ』(ヴァージニア・ウルフ著、鴻巣友季子訳)

どのような経緯で知ったのか忘れてしまいましたが、新潮文庫の『灯台へ』(ヴァージニア・ウルフ)を読んでみました。登場人物はそれなりにいますが、その中の誰かが主人公というわけでもありません。小説の舞台は、ほとんど動きませんし、時代は第一次世界大戦をはさむ前後となるある日の午後と十年後のべつの日の午前でしかありません。

 

登場人物の心の動きを描写することに目的がある作品で、その物語の筋書きに何か意味が(あるのかもしれませんが)あるようには見えません。ウィキペディアでは次のように紹介しています。

マルセル・プルースト『失われた時を求めて』や、ジェームズ・ジョイス『ダブリン市民』『ユリシーズ』と同じく、現代小説作家の伝統を継承、発展しており、『灯台へ』の物語の筋は、その哲学的内観に比べあまり重要ではない。意識の流れの文学的技法を代表する例として引用される。

 

この作品をどう読むのか、他の人はどう読んだのかということが気になります。これは、どう読むのが正解なのかという意味ではありません。この作品が心の動きを描写しているとしても、現実におきた何かのドキュメンタリーではなく、作者の作品であるからには、その描写には作者の意向があるはずです。もし何も考えずに執筆したというのであれば(それは考えにくいですが)、それはそういう作者の意向であると考えられるでしょう。

 

面白い作品だったかと問われれば、そのとおりとは言えませんが、ではつまらなかったのかというと、そうではありません。読みながら、その心情に共感できたり、何か閃いたりしましたが、それを言葉であらわそうとすると、うまく表現できずに消えてしまいます。

 

またいつか読み返してみようかと思います。その時に、今度はどのような感想を持つのか、それが楽しみです。

2025-05-10

外部環境で作成したコマプロをOpenVMSで動かす

Windows10上でsimh V3.8-1のVAX.EXEを用いて、OpenVMS VAX V7.2を動かしています。OpenVMS側で全て作業すれば問題ないはずですが、外部環境(Windows側とか、WSL環境とか)で作成したファイルをOpenVMS側に持ち込んで何かしようとすると、ひと手間かける必要があります。何をすれば良いのか分かってしまえば簡単なことなのですが、そこに至るまでは試行錯誤の連続でした。

 

ひとつの例として、外部環境で作成したOpenVMS用のコマンドプロシージャ(通称:コマプロ)をOpenVMSが動かすことを考えます。例えばFreeBSD環境で作成したコマプロがあるとしましょう。これをOpenVMS側に持ち込むには、いろいろな方法があるとは思いますが、ISOファイルを経由させます。FreeBSD側ではmkisofsを使ってISOファイルを作ります。これをsimhでデバイスにattachしておけば、OpenVMS側でマウントできます。ここで問題になるのは、ISOイメージの中にあるコマプロを直接実行しようとしてもエラーになることです。 


FreeBSDで作成したファイルなので、当然ながら、行末がLFになっています。このようなファイルをOpenVMSでは認識できないので、dir/fullで見ると「Record format:      Undefined, maximum 0 bytes, longest 0 bytes」となっています。そこで以下のコマンドで変換すればよいようです。

set file/attr=(RFM:STMLF) sample.com

 

 これを行えば、dir/fullで「Record format:      Stream_LF, maximum 0 bytes, longest 0 bytes」となるので、コマプロとして実行してもエラーになりません。

 

分かってしまえば簡単なことでしたが、ここに至るまでは苦労しました。Webで情報を検索しても、OpenVMSを利用している人が少ないためか、参考となる事例が見つかりませんでした。漠然としたアイディアとしては、FDLとかconvertなどを使うのではないかと考えたりして、かなり迷宮をさまよいました。最終的にGeminiにお伺いをたてたところ、ヒントが得られました。しかしGeminiの回答は、おそらくChatGPTもそうでしょうが、ハルシネーションのせいなのか、かなりもっともらしいものの微妙に誤りを内在しているものでした。役には立つのですが、盲目的な信頼をおくのは考えものかと思います。

 

2025-05-08

Firefox 138では「NHKプラス」が視られる

Webで見かけた記事「「Firefox 138」のリリースノートにない日本人にとって重要な変更とは?」によると、Firefox 138では「NHKプラス」が視られるようになっているとのことです。Windows10上のFirefox 138.0.1で試してみたところ、視聴できることを確認しました。

 

 「NHKプラス」でFirefoxが対象外となったのは、2022年4月27日付「【重要なお知らせ】NHKプラスアプリでの推奨OSの変更等について」でした。このお知らせでは、NHK側としては従来よりFirefoxを推奨してはいなかったものの、視聴することはできていたと記しています。しかし、Firefoxでは視聴できなくなりました。

 

Firefoxで「NHKプラス」が視られるのは、3年ぶりです。この間Firefoxでは視聴できなかった理由を、記事では次のように記しています。

 提供していただいた情報によると、「NHKプラス」ではPicture in Pictureを実現するための一部APIが実装されているかどうかを調べ、動画のストリーミングの可否を決定しているとのこと。「Firefox」はセキュリティ上の懸念からこのAPIを実装していないため、動画の視聴ができなかったそうです。

 

「NHKプラス」としては、接続しているブラウザが「Firefox」であることを確認しているのではないようなので、今回の復活につながったのでしょう。当時は視聴不可となる理由が不明だったので、ブラウザをFirefoxではないように見せかけることができれば何とかなるのだろうかと考えたものです。しかしブラウザ名を見ていたわけではないということです。

 

NHKとしてはFirefoxを推奨環境に加えたくなさそうなのですが、ブラウザ名でFirefoxを狙い撃ちにすることはないようです。

2025-05-07

時代劇などで「このクソじいじ」という台詞が聞かれる日がくるだろうか

大岡越前でも、暴れん坊将軍でも、水戸黄門でも何でもよいのですが、時代劇を見ていると暴れ者に襲われる庶民が登場するシーンがよくあります。そういうシーン(に限りませんが)などで、暴れ者が「このクソじじい」と罵る台詞が聞かれます。こういう台詞は、時代劇とはいえ歴史を忠実に反映している訳ではないので、今日の視聴者に馴染みのある表現になっています。もしかすると将来いつかは、「このクソじいじ」となる日が来るかもしれません。

 

まさか時代劇で「じいじ」などという台詞が現れるとは、僕自身は思っていないのですが、言葉の変化は予断を許しません。時代劇の表現が、その時代に忠実にしすぎると、 視聴者がついてこられなくなります。時代劇は、その時代を忠実に描くことも大切ですが、視聴者を楽しませることも大切なので、そのバランスをとる中で、今風の表現が出現する可能性もあるでしょう。

 

Webに「「じいじ ばあば」に虫酸が走る? 祖父母をどう呼ぶか問題 学者が読み解く“いま”を映す家庭内の距離感」という記事がありました。「じいじ」とか「ばあば」という表現が何時頃から使われているのか判然としませんが、2000年以降ではないかとみられます。この表現を嫌う人がいます(僕もそうです)が、むしろ喜んで使う人もいます。記事では次のように書かれています。

「『じいじ ばあば』は、『パパ ママ』同様、密な家庭のその関係の中だけで、特別に孫や子に呼んでもらえる名前。その点が大きいのではないでしょうか」
 そして「じいじ ばあば」を嫌う人が一定数存在する理由もそこにあると、石黒教授は言う。


祖父や祖母を表現する言葉として、「(お)じいさん/(お)ばあさん」、「(お)じいちゃん/(お)ばあちゃん」、「じじい/ばばあ」などが昔から使われてきましたが、今はそれに「じいじ/ばあば」が加えられています。しかしTVドラマでも実生活でも、人に呼び掛ける表現として、「おい、じいさん」、「おい、じいちゃん」、「おい、じじい」などは考えられますが、少なくも2025年の今では「おい、じいじ」は無いと思います。しかし将来は、当たり前になっている日が来るかもしれません。100年後ならあり得るかもしれません。もしかすると30年後にはなっているかもしれません。時代の変化は激しいので、10年後には普通に使われているかもしれません。

2025-05-06

simhの仮想磁気テープファイルをTAR形式ファイルに変換

Microsoft Windows10上のsimh V3.8-1 VAX.EXEを用いてOpenVMS V7.2の環境を作成しています。OpenVMS側からWindows10側にファイルを持ってくる方法を考えてみました。OpenVMS側ではTU-81で磁気テープにファイルを書き出せば、実はsimhにおける仮想磁気テープファイルとしてWindows10側でアクセスできます。この方法で何でもファイルを持ってこられるわけではないと思いますが、少なくともテキストファイルならば問題ないでしょう。

 

OpenVMSがTU-81に書き込む際にはANSI X3.27で規定されたフォーマットになっているようです。ここから、最低限としてテキストファイルを取り出せればよいとします。ただし複数ファイルが格納される可能性を考慮しておきます。ファイルを一つずつ取り出しても構わないのですが、ちょっと気をきかせて、TAR形式ファイルに変換しておこうかと思います。

 

変換スクリプトはWindows10上のWSL2にインストールしてあるUbuntu環境でPythonを使用しました。いろいろと不完全ではあるのですが、仮想磁気テープファイルに格納されているファイルを取り出してTAR形式ファイルに変換するスクリプトができました。

  • ANSI X3.27のヘッダ情報を解釈すれば長いファイル名にも対応できるのですが、それは見送りました。
  • 当面はテキストファイルだけで良いので、それ以外のファイル形式は未対応としました。
  • スクリプトで大域変数を多用していて、あまり良くないのですが、改善するのは将来の課題としました。

 

作成したスクリプトは、次のようになりました。Pythonでtarfileモジュールを使うと、簡単にTAR形式ファイルを作成できて、ありがたいことです。

 

#!/usr/bin/python3
import os
import sys
import tarfile

def vol1(r):
    # print("{}".format(r[:4]))
    # print("\t" "Volume Identifier[{}]".format(r[4:10]))
    # print("\t" "Accessibillity[{}]".format(r[10]))
    # print("\t" "Owner Identifier[{}]".format(r[37:51]))
    # print("\t" "Label-Standard Version[{}]".format(r[79]))
    return

def hdr1(r):
    global FileName
    global fd
    FileName = r[4:21].strip()
    fd = open(FileName,"w")
    # print("{}".format(r[:4]))
    # print("\t" "File Identificer[{}]".format(r[4:21]))
    # print("\t" "File-Set Identificer[{}]".format(r[21:27]))
    # print("\t" "File Section Number[{}]".format(r[27:31]))
    # print("\t" "File Sequence Number[{}]".format(r[31:35]))
    # print("\t" "Generation Number[{}]".format(r[35:39]))
    # print("\t" "Generation Version Number[{}]".format(r[39:41]))
    # print("\t" "Creation Date[{}]".format(r[41:47]))
    # print("\t" "Expiration Date[{}]".format(r[47:53]))
    # print("\t" "Accessibility[{}]".format(r[53]))
    # print("\t" "Block Count[{}]".format(r[54:60]))
    # print("\t" "System Code[{}]".format(r[60:73]))
    return

def hdr2(r):
    global RF
    RF = r[4]
    # print("{}".format(r[:4]))
    # print("\t" "Record Format[{}]".format(r[4]))
    # print("\t" "Block Length[{}]".format(r[5:10]))
    # print("\t" "Record Length[{}]".format(r[10:15]))
    # print("\t" "Buffer-Offset Length[{}]".format(r[50:52]))
    return

def hdr3(r):
    # print("{}".format(r[:4]))
    # print("\t" "RMS attribute[{}]".format(r[4:68]))
    return

def hdr4(r):
    # print("{}".format(r[:4]))
    # #print("\t" "Reserved[{}]".format(r[4:79]))
    # print("\t" "Filename[{}]".format(r[5:67]))
    # print("\t" "Length[{}]".format(r[67:69]))
    return

def eof1(r):
    fd.close()
    tar.add(FileName)
    os.remove(FileName)
    # print("{}".format(r[:4]))
    # print("\t" "File Identificer[{}]".format(r[4:21]))
    # print("\t" "File-Set Identificer[{}]".format(r[21:27]))
    # print("\t" "File Section Number[{}]".format(r[27:31]))
    # print("\t" "File Sequence Number[{}]".format(r[31:35]))
    # print("\t" "Generation Number[{}]".format(r[35:39]))
    # print("\t" "Generation Version Number[{}]".format(r[39:41]))
    # print("\t" "Creation Date[{}]".format(r[41:47]))
    # print("\t" "Expiration Date[{}]".format(r[47:53]))
    # print("\t" "Accessibility[{}]".format(r[53]))
    # print("\t" "Block Count[{}]".format(r[54:60]))
    # print("\t" "System Code[{}]".format(r[60:73]))
    return

def eof2(r):
    # print("{}".format(r[:4]))
    # print("\t" "Record Format[{}]".format(r[4]))
    # print("\t" "Block Length[{}]".format(r[5:10]))
    # print("\t" "Record Length[{}]".format(r[10:15]))
    # print("\t" "Buffer-Offset Length[{}]".format(r[50:52]))
    return

def eof3(r):
    # print("{}".format(r[:4]))
    return

def eof4(r):
    # print("{}".format(r[:4]))
    return

LABELS = {
    "VOL1":vol1,
    "HDR1":hdr1,
    "HDR2":hdr2,
    "HDR3":hdr3,
    "HDR4":hdr4,
    "EOF1":eof1,
    "EOF2":eof2,
    "EOF3":eof3,
    "EOF4":eof4,
}

def fixed(d):
    return

def variable(d):
    i = 0
    while i < len(d):
        try:
            l = int(d[i:i+4])
        except ValueError:
            break
        # print("{} {:04d} {:04d} {}".format(FileName, i, l, d[i+4:i+l]))
        fd.writelines(d[i+4:i+l])
        fd.write("\n")
        i = i + l

def spanned(d):
    return

RECORDS = {
    "F":fixed,
    "D":variable,
    "S":spanned,
}
RF = ""

def readrecord(f):
    global TapeMark
    len0 = int.from_bytes(f.read(4),'little')
    if len0 == 0:
        TapeMark += 1
        if TapeMark >= 2: raise EOFError
        return 0
    TapeMark = 0
    data = f.read(len0).decode()
    len1 = int.from_bytes(f.read(4),'little')

    label = data[:4]
    if label in LABELS:
        LABELS[label](data)
    else:
        #print(TapeMark, len0, data[:4], data[4:16])
        # print("DATA({})".format(len0))
        RECORDS[RF](data)

    return 0 if len0 != len1 else len0

def readblock(f):
    while True:
        if readrecord(f) == 0: break

TapeMark = 0
FileName = ""
fd = 0
tar = 0

tar = tarfile.open("tap2tar.tar.gz","w:gz")
with open(sys.argv[1],"rb") as f:
    while True:
        try:
            readblock(f)
        except EOFError:
            break
tar.close()
#[EOF]

2025-05-03

TW5にはViewTemplateというものがあるらしい

TiddlyWikiには旧いTWCと新しいTW5があります。TWCの頃から利用しており、今はTW5を使っていますが、活用できているとは言えません。Talk TiddlyWikiという「the TiddlyWiki 5 Discourse discussion group for end users」があるので、いつも見るようにしているのですが、その質問にも議論にもついていけません。いろいろな機能があるんだなぁと思いますが、それを使いこなすことができれば、TW5の可能性がもっと拡がると思うので、勉強したいと思います。

 

そこを見ていたら、「ViewTemplate」というものがあるのを知りました。どのように利用するのかわからないので、Webを検索しながら試行錯誤してみました。なんとなく使い方が見えてきて、「$:/tags/ViewTemplate」というタグをつけてたTiddlerを作っておくと、その内容が、他の全て(または条件の合致するもの)のTiddlerにも自動的に表示されるようです。

 

どのような動作をするものなのかは判明しましたが、これを使うと助かる状況が何なのか、まだわかりません。公式サイトには「SystemTag: $:/tags/ViewTemplate」という情報がありますが、もうちょっと詳しい説明が欲しいと思います。

VirtualBox上のFreeDOSでTurboPascal

特別に何か積極的な意図があるわけではないのですが、VirtualBox上にFreeDOSをインストールしてみました。独立したMS-DOSは1993年のV6が最後ですし、PC-DOSも1998年のPC-DOS 2000が最後なので、今はFreeDOSが唯一の選択肢です。Windows10にもCMD.EXEの環境はありますが、純粋なDOSを使ったのは久しぶりです。昔々のDOSっぽいところも残っていますが、だいぶ洗練されていると感じました。

 

ここでふと思い出しましたが、確かTurbo Pascalが自由に使えるようになっていたはずです。もっと本格的なFree Pascalというものもあるようなのですが、DOS時代の思い出にひたるにはTurbo Pascalの方が楽しそうです。もっとも僕自身としては、当時Turbo Pascalを使ったことはなく、Turbo Cを使っていました。

 

ZIPファイルをダウンロードしたら、「tp302」というディレクトリの下にファイルがありました。たったこれだけ?と思ったくらいファイル数が少なかったのですが、フロッピーが当たり前だったDOS時代なら、こんなものかもしれません。展開したファイルをディレクトリごとFreeDOS環境にコピーしたのですが、なぜかTINST.COMが動きません。四苦八苦し、Webを検索したら「Turbo Pascal 3.02 を Windows 10 (64bit) / 11 にインストールしてみる」という記事が見つかりました。そこに以下の記述があり、ディレクトリを「tp3」としたら動くようになりました。

解凍すると TP302 フォルダができます。リネームして TP3 としておきます。

 

VirtualBox上のFreeDOS環境と、ホストであるWindows10の間でファイルをやりとりする必要があるのですが、どのような方法が考えられるのでしょうか。これもWebで調べてみたら、「Exchanging Files with the FreeDOS machine」という記事が見つかりました。もっとも簡単なのは「Mount the image file」という方法のようです。現在のWindowsはVHD形式の仮想ディスクをマウントできるそうなので、VirtualBox上のFreeDOSをVHD形式の仮想ディスクにインストールすれば、それをWindows10でマウントできます。

 

試してみたのですが、VHDファイルをダブルクリックしてもマウントできませんでした。またまたWebに助けを求めると「Windows 10でVHDファイルをドライブとしてマウントする」という記事がありました。この記事によると、ダブルクリックしてもマウント出来ないことがあるようで、その場合でも「コンピュータの管理」からマウントすることはできるそうです。その手順に従うと、確かにマウントできました。