Hello, worldを読む

RDTを試した際、次のようなコードを書きました。

#
# 由緒正しいハローワールド
#

print("Hello, world")

まずは、これが一体なんだったのか、というところから見ていきます。
ちなみに、このプログラムを実行した結果は、

Hello, world

というメッセージが表示されるだけのものです。
しかし、これはかのK&Rに発端を成し、以来プログラミングを志すものの第一歩としてイニシエーション的な役割を持つ、世界共通の伝統的プログラムなのです!
……というのが大げさかどうかは寡聞にして知りません。


ともかく、この実行結果から、このコードの内容を推測してみます。
以前調べたことですが、プログラミングというのはコンピュータに対しての命令を記述することでした。
今回このようなメッセージが表示された以上、ここには『メッセージを表示せよ』という命令が書いてあるに違いありません。

print("Hello, world")

print、というそれらしき名前から見て、この1文がそれに該当するはずです。


さて、推測するばかりではなく、ちゃんと資料を確認してみましょう。
Ruby公式サイトドキュメントページを見に行きます。
Rubyの文法やライブラリのAPIなどはリファレンスマニュアルを見よ、とのことなので早速移動。
流石に非常によく整理されたドキュメントのようです。
しかし、あくまでもリファレンスなので、入門者が頭から読んで勉強するのに向いているようには見えません(人によるのかもしれませんが)。
今回は取り敢えず『print』という名称から情報を探ってみようと思うので、索引へ飛び込みます。
するとRubyにおける命令らしきものがずらりと並んでます。この中から『print』を見つけます。辞書順なのですぐ見つかるはずです(Ctrl + fで検索しても良いです)。
そうすると、『print』に対しては5つの項目が結び付けられています。

  • IO
  • OpenSSL::SSL::SSLSocket
  • StringIO
  • Zlib::GzipWriter
  • 組み込み関数

今回は、この中の最後の項目、“組み込み関数”をチェックします。

print([arg1[, arg2, ...]])

引数を順に出力します。引数が与えられない時には変数 $_ の値を出力します。文字列以外のオブジェクトが引数として与えられた場合には、当該オブジェクトを to_s メソッドにより文字列に変換してから出力します。ただし、nil に対しては文字列 "nil" を出力します

変数 $, (出力フィールドセパレータ)に nil でない値がセットされている時には、各引数の間にその文字列を出力します。変数 $\ (出力レコードセパレータ)に nil でない値がセットされている時には、最後にそれを出力します。

nil を返します。

('A`)


なんだか一応『出力します。』と最初の文に書いてあるので、これが何らかを出力するための命令なのは確かなようです。
で、何を出力するかというとそれは『引数』だよ、というお話のようです。

関数とか引数とか

まぁまずはお約束なので、謎の言葉を解き明かしていきます。


・引数ってなんですか?

引数(ひきすう、argument=実引数 または parameter=仮引数)とは、プログラミング言語において関数やメソッドを呼び出すときに、その関数やメソッドを実行するために渡す値のこと。

引数は「ひきすう」と読むらしいです。「いんすう」ではありません。
そして、関数・メソッドを呼び出す際に渡す値の事らしいです。
関数、ときくと遠い昔に数学だか算数だかの授業で聞いたような気がしなくもありません。


・関数とはなんでしょう?

関数(かんすう)とはサブルーチンの一種で、特にある値を引数として受け取り、その結果たる値を返す性質をもつものを指す。このとき返される値を戻り値(もどりち)や返り値(かえりち)のように呼ぶ。

引数としてとりうる値の集合から、戻り値としてとりうる値の集合への写像のように捉えることができるため関数と呼ばれるが、次の点で数学の関数とは異なる。

* 引数が同じでも状況に応じて戻り値が異なる(状態を持つ)
* 関数の処理の実行によってシステムに変化が発生する(副作用を持つ)
* 戻り値が存在しない場合がある

どうやら数学でいう関数とはちと違うようです。

Excelでの関数は、主に、計算をしたり、データーの検索や集計をしたり、表示を変換したりする。合計値を求めるSUM関数や、平均値を求めるAVERAGE関数など、100を超える関数が多数存在する。

ということで、それなりに馴染みのありそうなところだと、ExcelのSUMとかIFとかVLOOKUPとかのあれのことらしいです。

そういえば、確かに関数って書いてあります。
要するに関数というものは、『引数と呼ばれる値を渡すと、中で何やらごちゃごちゃやって期待する結果を返してくれるモノ』という感じでしょうか。
こうして聞くと一種のブラックボックスみたいな存在という印象ですが……

自動販売機は関数だと思ってみる

今の頭の中では、関数というものは……

  • なんか渡す(引数)
  • なんか中でごちゃごちゃする(処理)
  • なんか返ってくる(戻り値)

……という理解になってます。


これって実世界に当てはめてみると、自動販売機とかそんなイメージじゃない?ということでこんなの描いてみました。

ギャグだと思われると悲しいのですが、これでもExcelで頑張りました。酷い図で申し訳ないです……
関係ありませんが、私はタバコ吸わないので自動販売機といえば飲み物です。
描いてみて「こんな感じかなぁ……」なんて眺めてたのですが、これだと、

  1. お金入れる
  2. 何かする
  3. 飲み物出てくる

という流れになってしまう……飲み物選択の自由はなし。
それじゃ困るので修正。

どれが欲しいか?という情報も自動販売機に渡してあげなければいけない気がします。
こんな感じで例えば『自動販売機関数』なんてのを考えてみると、

関数名 自動販売
引数 お金、欲しい飲み物がわかる情報
戻り値 飲み物

という感じでしょうか?
でもこれだとお釣りの扱いとか困りますね……このあたりのことは、後々の話題で解決するような気がします。


関数については、今のところこれくらいの“イメージ”を持っておけば大丈夫でしょう。

改めて、print関数

ちょっと寄り道が過ぎた気がしますが、printの話題に戻ってみます。
先ほどリファレンスマニュアルから引用した文に、

print([arg1[, arg2, ...]])

という部分がありました。
これは、print関数の使い方を示しています。
arg1、arg2と書かれているのは先ほど引数の説明にあった“argument(実引数)”のことです。
つまりprint関数を使うときには、printに続いて引数を小括弧で囲んだ形で記述すれば良いようです。
実際、Hello, worldプログラムでは、

print("Hello, world")

としてprint関数を呼び出していました。
これはつまり、小括弧のなかの『"Hello, world"』がprint関数の引数にあたり、これを出力してください、とコンピュータに命令しているのです。

組み込み関数とは

ところで、先ほどからprint関数と呼称していますが、リファレンスマニュアルのタイトルには

Rubyリファレンスマニュアル - 組み込み関数

と書いてあります。そういえば索引から来たときもそんな言葉が書いてありました。
この“組み込み関数”というのはなんでしょうか。
このページの先頭を改めて確認してみますと、次のようなことが書かれています。

Ruby には厳密な意味では関数はありませんが、Kernel モジュールで定義されているメソッドは (どこからでも関数形式で呼び出せるので) 他言語における関数のように使えます。これらのメソッドを再定義する場合は他の場所への影響を考えて行なう必要があります。

衝撃の事実。
実は、Rubyには“関数”はないようです。
ただし、Kernelモジュールで定義されたメソッドを、特別に組み込み関数と呼ぶようです。


またモジュールとかメソッドとか……このあたりの言葉については、ひとまず後回しにしましょう。
明日はリテラルについて書こうと思います。