---
title: そのコメント、誰が検証していますか
tags:  #プログラミング #ドキュメント  
author: [hirotaka kono](https://image.docswell.com/user/hk_it7)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/KJ4W19RY71.jpg?width=480
description: 大Funabashi.dev 登壇資料 『そのコメント、誰が検証していますか』 2026/9/12  「例外を投げる」と書いてあるのに nil を返すメソッド。YARD にかけても警告ゼロ、 ドキュメント化率は 100%。コメントの嘘は、誰が検出してくれるのか。  Ruby / PHP / Java / Deno / Rust の5言語で、ドキュメントコメントが何を検証できて 何ができないのかを、実際にツールに通して確かめました。  同じ情報が2箇所にあると必ずズレる。答えは「距離をゼロにする」「ズレを検出する」 「諦める」の3つしかありません。
published: September 12, 26
canonical: https://image.docswell.com/s/hk_it7/K1QEY2-dai_funadev-docs
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/KJ4W19RY71.jpg)

/**
* &lt;b&gt;そのコメント、誰が検証していますか&lt;/b&gt;
*
* Ruby / PHP / Java / Deno / Rust のドキュメントコメントは
* 何を検証できて、何ができないのか。
* そして、いま書くべきことは何か。
*
* @author こうの
* @see
*/
&quot;大Funabashi.dev&quot;


# Page. 2

![Page Image](https://bcdn.docswell.com/page/LE1YGKQN7G.jpg)

# &lt;b&gt;例えば、こう書いたとする&lt;/b&gt;
#
# Ruby のドキュメントコメントは # で書く。
# 型は @param / @return にタグとして書ける。
# ユーザーを取得する。
# 見つからない場合は RecordNotFound を投げる。
#
# @param [String] user_id ユーザーID
# @return [User] 見つかったユーザー
def find_user(user_id)
nil
end
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/GEWGKDLMJ2.jpg)

# &lt;b&gt;YARD にかけてみる&lt;/b&gt;
#
# YARD は Ruby のドキュメント生成ツール。
# 「例外を投げる」と書いて nil を返しているが、さて。
$ yard doc
Methods: 1 (0 undocumented)
100.00% documented
警告ゼロ。ドキュメント化率は満点
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/47ZLZGMMJ3.jpg)

/**
* &lt;b&gt;今日の軸&lt;/b&gt;
*
* &lt;ol&gt;
*
&lt;li&gt;検証できるか —— 嘘を検出できるか
*
&lt;li&gt;距離 —— 同じ情報が、何箇所に書かれているか
* &lt;/ol&gt;
*
* @see &quot;Ruby はいま見ました。あと4言語&quot;
*/
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/YJ6WZYN5JV.jpg)

/**
* &lt;b&gt;PHP：こう書いたとする&lt;/b&gt;
*
* PHPDoc は Javadoc に近い記法で、太字は HTML タグ。
* 型は書けるが、PHP 本体はこれを読まない。
*/
/**
* @return array&lt;int, User&gt;
*/
function getUsers(): array {
return [&#039;a&#039; =&gt; &#039;not a user&#039;];
}
「 User の配列を返す」と書いてある。この型は PHP の言語仕様にはなく、コメントにしか書けない
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/GJ5MWG5GJ4.jpg)

/**
* &lt;b&gt;PHP：かけてみる&lt;/b&gt;
*
* 同じファイルを、2つのツールにかける。
*/
$ php -l users.php
No syntax errors detected
# PHP 本体の構文チェック
$ phpstan analyse users.php
# 静的解析ツール
should return array&lt;int, User&gt;
but returns array&lt;string, string&gt;
PHP 本体はコメントを無視する。PHPStan はコメントを型として読む
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/9E29QYND7R.jpg)

/**
* &lt;b&gt;Java：こう書いたとする&lt;/b&gt;
*
* Javadoc は HTML を書ける記法なので、太字はタグ。
* コード例は {@code @snippet} で別ファイルを参照する。
*/
snippet-files/CalcSnippets.java（実在するコード）
// @start region=&quot;basic&quot;
int result = Calc.add(1, 2);
// @end
Calc.java（ドキュメント側）
/**
* {@snippet class=&quot;CalcSnippets&quot; region=&quot;basic&quot;}
*/
ドキュメントに書くのは「どのファイルのどの範囲か」だけ
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/D7Y4WGPMEM.jpg)

/**
* &lt;b&gt;Java：javadoc は HTML を生成する&lt;/b&gt;
*
* コマンドを実行すると、このコメントが HTML になる。
*/
{@snippet}
の参照先が、そのまま展開されている
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/VENY9G53J8.jpg)

/**
* &lt;b&gt;Java：参照先を壊してみる&lt;/b&gt;
*
* 参照する region の名前を、わざと間違える。
*/
Calc.java — region 名を typo させる
{@snippet class=&quot;CalcSnippets&quot; region=&quot;typo&quot;}
$ javadoc -Xdoclint:none ...
error: region not found: &quot;typo&quot;
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/Y79P2WYPE3.jpg)

/**
* **Deno：こう書いたとする**
*
* JSDoc のコメント。中身は Markdown なので、
* 太字はアスタリスク2つ。
*/
mod.ts
/**
* ```ts
* assertEquals(add(1, 2), 999);
* ```
*/
export function add(a: number, b: number): number {
return a + b;
}
コメントに書いた「使用例」。ただし 1 + 2 は 999 ではない
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/G78D5N6X7D.jpg)

/**
* **Deno：テストを走らせる**
*
* Deno は JavaScript / TypeScript のランタイム。
*/
Deno — JavaScript / TypeScript のランタイム
$ deno test --doc
# --doc: ドキュメント内のコード例もテストする
error: AssertionError: Values are not equal.
3
+
999
型が違えば TS2322 。型チェックも実行も両方される
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/L7LMYP9NJR.jpg)

//! **Rust：こう書いたとする**
//!
//! rustdoc のコメントは /// と //! で書く。
//! 中身は Markdown。
README.md
# demo
```rust
assert_eq!(add(1, 2), 999);
```
src/lib.rs — これ1行だけ
#![doc = include_str!(&quot;../README.md&quot;)]
README の中身を、そのままこのライブラリのドキュメントにする
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/4EMYN4ZQEW.jpg)

//! **Rust：テストを走らせる**
//!
//! README に書いた例が、テストとして実行される。
$ cargo test
test src/lib.rs - (line 5) ... FAILED
assertion `left == right` failed
left: 3
right: 999
README に書いた例が doctest として実行されている
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/PER9DW6KJ9.jpg)

//! **実在のライブラリでも**
//!
//! clap は Rust の定番コマンドライン引数パーサ。
clap/src/lib.rs:411
#![doc = include_str!(&quot;../examples/demo.rs&quot;)]
動くサンプルプログラムが
そのままドキュメント
toml / image は README を、axum は章ごとの Markdown を埋め込んでいる
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/P7XQ1PM5EX.jpg)

同じ情報が2箇所にあると
必ずズレる
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/37K92DGR7D.jpg)

/**
* &lt;b&gt;答えは3つしかない&lt;/b&gt;
*/
距離をゼロにする Rust include_str! / Java {@snippet}
ズレを検出する doctest（Deno / Rust）/ PHPStan / doclint
諦める
YARD の型タグ
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/LJ3W4RNGJ5.jpg)

# &lt;b&gt;では、こう書いた場合は？&lt;/b&gt;
# ユーザーを取得する
def get_user
情報量ゼロ
名前から100%予測できる＝読んでも何も新しく分からない
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/8JDKQYWNEG.jpg)

ドキュメントの価値
＝
コードから予測できない度合い
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/VEPKL69N78.jpg)

/**
* &lt;b&gt;読者が変わった&lt;/b&gt;
*
* &lt;p&gt;&lt;b&gt;昔&lt;/b&gt; —— 未来の誰か。非同期・不特定。だから網羅的に、丁寧に。
* &lt;p&gt;&lt;b&gt;今&lt;/b&gt; —— 今のAIと、今の自分。同期的・具体的。
*/
19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/27VVQ3MY7Q.jpg)

AI時代に一番効くのは
実行されるドキュメント
嘘をつかないから
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/5JGLW3GW7L.jpg)

/**
* &lt;b&gt;コードから予測できないことだけ書けばいい&lt;/b&gt;
*
* &lt;p&gt;そして、書いたなら検証する。
*
* @author こうの
* @see
&quot;大Funabashi.dev&quot;
*/
21


