コーディング規約「リテラル禁止」
— なぎせ ゆうき (@nagise) April 16, 2021
「null書くなって事ですかねw」
「えっ?」
「えっ?」
Q. リテラル(literal)とは何か?
A. 言語による
なんでこんな記事を書いているかというと、リテラル禁止FizzBuzz大会がいまいち盛り上がらなかったので、ルール解説をして参加者を増やそうという目論見である。
リテラル禁止FizzBuzz大会、開幕!(待て https://t.co/zpIirtNpmO
— nishio hirokazu (@nishio) April 16, 2021
Java言語におけるリテラル
コンピュータプログラミング言語においてリテラルは、ソースコード内に値を直接表記したものをいう。言語によってリテラルとして表記できる型の種類や表記方法は異なる。
という感じで、 42 とか "hoge" とかそういう値を直書きしたものを言う。このあたりは雰囲気で把握している人も多いだろう。ではその明確な範囲としてどこまでがリテラルか?となると、言語ごとのルールブック、つまるところ言語仕様に当たらなければならない。
Java言語仕様は怖くない。インターネットでオープンにされており、非常にアクセスしやすい。 Java SE Specifications のページに各バージョンの言語仕様へのリンクがまとめられている。
2021年9月には次期LTS(長期サポート)版のJava17がリリースされるが、本稿執筆時点でのLTSはJava11なのでJava11の言語仕様を元に調べてみよう。
物事を調べるには原典にあたることが大事である。原典をみて誰かが本を書いたりblogを書いたりする。それを見て書かれたblogは原典を見たものより信頼度が落ちる。孫引きして書かれた引用元も示されてないような記事を信頼してはしてはいけない。
"The Java Language Specification, Java SE 11 Edition" の "HTML"のリンクを辿ると The Java® Language Specification Java SE 11 Edition の目次に辿り着ける。
リテラルについて書かれているのは 3.10. Literals の部分だ。Java言語仕様は英語で書かれているが、現代は機械翻訳が優秀なので、機械翻訳でもある程度概要をつかむことができるのではないだろうか。また過去には公式に日本語訳がされたものが出版されたこともあるが、Java5の内容の
Java言語仕様-第3版 (2006年)が出たのが最後となっている。
Literal:
IntegerLiteral
FloatingPointLiteral
BooleanLiteral
CharacterLiteral
StringLiteral
NullLiteral
と列挙されていて、各項目の説明が以下に続く。
各リテラルの詳細な定義まではここでは立ち入らないが、ざっくりと表にすると
種類 | 概要 | 例 |
---|---|---|
IntegerLiteral | 整数の数値 | 42 0xCAFEBABE 0b0010_1111 |
FloatingPointLiteral | 浮動小数の数値 | 1.234 |
BooleanLiteral | boolean型の値 | true false |
CharacterLiteral | charの値 | 'A' |
StringLiteral | 文字列 | "hoge" "" |
NullLiteral | null | null |
といった感じ。
また、 3.10. Literals に記載されていないが 15.8.2. Class Literals という項目があって、classリテラルについて記載がある。これも Java言語における「リテラル」に含めそうだ。
これは Hoge.class などといったように、クラス名に .class とつけることで java.lang.Class オブジェクトをリテラルとして表す記法。
リテラルを使わないでFizzBuzzをしてみよう!
さて、以上でJavaにおける「リテラルの禁止」の指す範囲が明確になったと思う。
プログラミングパズルが好きな人は是非、リテラルを用いないFizzBuzzに挑戦してみて欲しい。たぶん、セミコロンを使わないFizzBuzzよりは簡単じゃないかな。(参考: セミコロンレスJava はチューリング完全か? - プログラマーの脳みそ )
セミコロンレスJavaもそうだが、この手のプログラミングパズルは標準APIの範囲で行うことが暗黙の了解となっている。
僕も書いてみたけども芸術点がイマイチなのでまだ満足できていない。
空気を読んだ話
一般に「リテラルを使うな」というのはプログラムコード中にマジックナンバーなどを直接記載しないということを意図したものである。なんらかの意味のあるフラグの値などは定数定義(Javaの場合はstatic finalフィールドにするかenumにすることが多いかな)して間接的に用いることを指す。
言語仕様上のリテラルを一切用いないというのは揚げ足取り的な話で、しかしここではネタとしてその制限でプログラミングを書けるか?という設問がおもしろいので取り上げている。
訂正
2021.04.19 BuzzをBullと誤っていた箇所があったので修正