📏

イベントハンドラ名のプレフィックス「on」の解釈

2024/05/20に公開

はじめに

「プログラムは英語の自然言語に近くなるように」というテーマで命名を検討するに当たって、イベントハンドラに付与するonプレフィックスについての質問を受けました。
なんとなくはわかるもののうまく言語化できず、良い機会なので調べてみました。

その調査結果として、どのように捉えれば上記テーマと齟齬が生じないのか、一つの解釈を提示してみます。
※あくまで一つの解釈です。

前置詞 on の意味

まずは前置詞としてのonの意味を掘り下げます。
用途として多いのは「上に」に類するものですが、本来は「接触している」状況を表していたのだそうです。
そこから「上側に接している」という意味で使用されたり、「時間に接している」ということで on Mondayon schedule という用法が用いられたりするようになったようです。

更にそこから転じて、「on + 動作を表す名詞/動名詞」で「〜するとすぐに」という意味を持つようにもなりました。

Oxford Advanced Learner's Dictionaryの例文が分かりやすかったです。

immediately after something

  • On arriving home I discovered they had gone.
  • Please report to reception on arrival.
  • There was a letter waiting for him on his return.

イベントハンドラの on プレフィックスはこの用法を利用していると考えられます。

また、英語の掲示板では、 on がタイミングを示す意味で使われることから、 when のタイプ数を減らすために代わりにonが用いられたのではないか、という意見もありました。
このどちらかで整理できそうな気がしてきました。

利用パターン別解釈

event 構文での解釈

まずはC#の event 構文での命名を考えます。

event構文利用箇所の命名
public class Enemy
{
    public event EventHandler OnDead;
}

public class Player
{
    public void StartBattle(Enemy enemy)
    {
        enemy.OnDead += () => this.FinishBattle();
        ...
    }
}

これの enemy.OnDead += () => this.FinishBattle() の部分を英文にすると下記のようになります。
()は省略されている単語を補った部分です。

  • on をそのまま使うパターン
    • On enemy's (being) dead, finish battle.
  • onwhen に置き換えるパターン
    • When enemy (is) dead, finish battle.

翻訳サイトで日本語に翻訳してみましょう。

  • On enemy's being dead, finish battle.
    • →敵が死んだら戦闘終了。
  • Finish battle on enemy's being dead.
    • →敵が死亡した時点で戦闘を終了する。
  • When enemy is dead, finish battle.
    • →敵が死亡したら戦闘終了。

きれいな文章になりましたね。
命令文として扱ってほしいところが主語省略版の平叙文として訳されてしまってはいますが。

イベントハンドラメソッドでの解釈

では、イベントハンドラメソッドに on プレフィックスを付与するのはどのように解釈できるでしょうか。

イベントハンドラメソッドの命名
public class Authentication
{
    public static event EventHandler OnSucceeded;
}

public class MainView
{
    public MainView()
    {
        Authentication.OnSucceeded += this.OnAuthenticationSucceeded();
    }
    
    private void OnAuthenticationSucceeded() 
    {
        this.OpenWindow();
    }
}

これの OnAuthenticationSucceeded() => this.OpenWindow() の部分を英文にすると下記のようになります。
()は省略されている単語を補った部分です。

  • on をそのまま使うパターン
    • On authentication's (having been) succeeded, open window.
  • onwhen に置き換えるパターン
    • When authentication (has been) succeeded, open window.

翻訳してみましょう。

  • On authentication's having been succeeded, open window.
    • →認証が成功したら、ウィンドウを開きます。
  • When authentication has been succeeded, open window.
    • →認証に成功したらウィンドウを開きます。

こちらもきれいな文章にできました。

イベントハンドラのような扱いのメソッドでの解釈

多用は避けたいですが、依存の方向が「処理を行うクラス→タイミング決めるクラス」ではなく逆の場合があります。
こういう場合はevent構文は使用できないので、外から直接メソッドを呼び出すことになります。

イベントハンドラのような扱いのメソッドの命名
public class CharcterSelectionView
{
    private OnSelectedCharacterIndexChanged(int index)
    {
        var character = this.characters[index];
        character.OnSelected();
    }
}

public class Character
{
    public void OnSelected()
    {
        this.SayHello();
    }
}

これのcharacter.OnSelected()の部分を英文にすると下記のようになります。
()は省略されている単語を補った部分です。
このパターンの場合はonをそのまま使うよりwhenに置き換えた方が理解しやすい文章になります。

  • onをそのまま使うパターン
    • Character, (do process for) on (your being) selected.
  • onwhenに置き換えるパターン
    • Character, (do process for) when (you are) selected.

翻訳してみましょう。Characterのままだと不自然な文章なため上手く訳してくれなかったので、Johnにしてみました。

  • John, do process for on your being selected.
    • →ジョン、あなたの選択に関するプロセスを行います。
  • John, do process for when you are selected.
    • →ジョン、あなたが選ばれたときの手続きをしてください。

話の繋がる文章になりました。

do process for の省略だなんて無理矢理だ」と感じるかもしれません。
しかしこの部分は「do things for」等複数の表現が可能な大した意味を持たない部分なので省略し、大事な部分のみ残して簡潔に意図が伝わるようにした、という見解は可能なのではないかと考えます。

しかし、イベント駆動にできそうな場合は、そちらを軸に設計を行うのが適切な場面が多いように思います。

その他の解釈

OnClick or OnClicked

言語やフレームワークにより両方の命名パターンが存在し、これまでそれぞれどういう思想なのか自信を持って説明できずにいました。
しかし今回調査を行なって、下記のような解釈で良いのではないかと整理できました。

「on + 動作を表す名詞/動名詞」で「〜するとすぐに」となる
ここから以下のパターンが作れます。

  • on click = on + 動作を表す名詞
  • on (being) clicked = on + 動作を表す動名詞

「click」は動詞の原型ではなく、名詞だったのですね。

「on + イベント名」という解釈

「on + 動作を表す名詞/動名詞」で「〜するとすぐに」を意味するので、「on + イベント名」で「〇〇イベント後すぐに」を表すと考えることも可能です。

OnButtonClick = on button's click event

翻訳してみましょう。

  • On button's click event, show message box.
    • →ボタンクリックイベントでメッセージボックスを表示します。

省略部分の補完量が少ないので、まずはこちらの考え方で慣らすというのはアリかもしれません。

リリテックラボ

Discussion