トップレベルのメソッド

今回はメソッド定義です。 メソッド定義はRubyの核心ですが、今回はトップレベルに限って説明します。 この限定によって、内容はかなり易しくなっています。

トップレベルに限ればメソッド定義はCの関数定義とほとんど変わりません。

メソッド定義と実行

メソッドはdefからendまでで定義をすることができます。

def example
  print "Hello world.\n"
end

example

このプログラムを説明しましょう。

  • defの後にメソッド名を書く。 このメソッドはexampleという名前のメソッド。
  • endの前までがメソッドの本体。 ここでは「Hello world.と表示する」ことを定義。 定義中は実行はしない。 定義と実行は別
  • メソッドを呼び出すにはメソッド名を書く。 メソッドは呼び出されると、自身を実行する

このプログラムexample4.rbというファイルの保存し、実行すると次のようになります。

$ ruby example4.rb
Hello world.
$

定義したメソッドは何回でも呼び出せます。

def example
  print "Hello world.\n"
end

example
example
example

これを実行すると

$ ruby example4.rb
Hello world.
Hello world.
Hello world.
$

となります。 また、前回学んだイテレータを使うこともできます。

def example
  print "Hello world.\n"
end

3.times do
  example
end

実行結果は前と同じです。

$ ruby example4.rb
Hello world.
Hello world.
Hello world.
$

Cを学んだ人ならば、メソッド定義はCの関数定義に似ていると思うでしょう。 現時点ではそのような理解で良いと思います。

パラメータと引数

メソッドにはパラメータを付け加えることができます。 パラメータは括弧の中にコンマで区切って書きます。

def sum(a, b)
  a + b
end

print sum(5, 10)
print "\n"

実行すると15が表示されます。

  • sumメソッドには2つのパラメータabがある
  • メソッドsuma + bを計算する
  • メソッド定義で最後に計算された値が、そのメソッドが実行されたときの「値」になる
  • print の引数はsum(5, 10)である。sum(5, 10)はメソッドsumに引数5と10を与えて実行したときの「値」である。 5と10はパラメータのaとbに代入され、メソッドにより5+10=15が計算され、15が値として返ってくる。 したがって、printは15を表示する
  • 最後にprintは改行を画面に出力する

「パラメータ(parameter)」と「引数(argument)」という言葉の区別ですが、

  • メソッド定義でメソッド名の後ろの括弧にある文字(aやb)はパラメータ
  • メソッド呼び出し(メソッドを実行すること)のときにメソッド名の後ろの括弧につけるオブジェクト(5や10)が引数

です。

Rubyでは括弧を省略することができます。 そのとき必要に応じて空白を入れて区切りを明確にします。

def sum a, b
... ... ...
print sum 5, 10

括弧は演算の順序を示すときにも使われます。

(2+3)*(4+5)

この括弧は省略できません。 省略すると

2+3 * 4+5

これは、2+12+5=19になってしまうからです。 *の両側に空白があったからといって、2+34+5を先に計算してはくれません。

Rubyではメソッド名と左括弧の間に空白を入れないことが大事です。 一般にRubyではメソッドの括弧を省略しそこに代わりの空白を入れることが可能なので、構文の解釈に曖昧さが生じます。

def double x
  2*x
end

print double (2) + 3
print "\n"

print double(2) + 3
print "\n"

これを実行すると

10
7

と表示されます。 最初のdoubleの呼び出しではdouble(の間に空白があるので、メソッドの括弧が省略され、(2)が計算の順序を表す括弧だと解釈されたのです。 それで、まず(2)+3=5を計算して、その5をメソッドdoubleに引数として渡し、2倍され、10が表示されたのです。 つまり、

double((2)+3)

と解釈されたのです。

2番めのdoubleの呼び出しではdoubleの直後に(があるので、括弧が引数を表す括弧だと解釈され、2が倍になって4、そのあと3が加えられて7が表示されました。

(double(2))+3

このようなことが生じるのは、Rubyが括弧の省略を許しているためです。 とにかく、メソッドの括弧はメソッド名の直後に書くようにしてください。

if文

多くの言語と同じようにRubyにもif文があります。

def even_or_odd(n)
  if n.even?
    print "偶数です\n"
  else
    print "奇数です\n"
  end
end

even_or_odd(3)
even_or_odd(6)

実行すると

奇数です
偶数です

となります。

  • メソッド名にアンダースコア(_)も使える
  • パラメータnは整数だと仮定する。整数のメソッドeven?を呼び出す。 このメソッドはnが偶数ならtrue(真)、そうでなければfalse(偽)を返す。
  • if文では、ifの後ろが真であれば直後を実行し、偽であればelse以下を実行する。 なおif文の「真」とは、「falseでもnilでもない」こと。 falseやnilもオブジェクトの一種。 したがって、整数の0や空文字列”“は真とみなされる。

ifの右側を「条件」といいますが、ここにはいろいろな演算子が使えます。 良く用いられるのは

  • == 等しい
  • > 左が大きい。>=左が大きいかイコール
  • < 右が大きい。<=右が大きいかイコール

などです。

  • else以下は省略できる
  • ifとelseの間にelsifを入れることができる。 前のif(またはelsif)の条件が偽でelsifの条件が真のとき、直後の文が実行される

再帰呼出し、パラメータのスコープ

メソッドのパラメータはそのメソッドの中でのみ有効です。 これはメソッド定義でもメソッド呼び出しでもそうです。 これをパラメータのスコープといいます。 スコープは有効範囲ともいいます。

メソッドが複数回呼び出されるとき、それぞれの呼び出しに対応するパラメータはすべて別変数になります。 このことは再帰呼出しをするときに重要になります。

def fact(n)
  if n<1
    nil
  elsif n==1
    1
  else
    n*fact(n-1)
  end
end

print fact(5)
print "\n" 

これを実行すると

120

と表示されます。

  • ここでは引数nは整数であると想定する
  • 引数nが1より小さければnilを返す
  • 引数nが1ならば1を返す
  • それ以外(1より大きな整数)のときは、nにn-1のときのfactの値を掛けて返す

最後が複雑ですが、順に考えればわかりやすいです。

  • n=2のときは「n=1のときのfactは1なので、2*1=2」
  • n=3のときは「n=2のときのfactは2なので、3*2=6」
  • n=4のときは「n=3のときのfactは6なので、4*6=24」
  • n=5のときは「n=4のときのfactは24なので、5*24=120」

このメソッドは定義の中で自分自身を呼んでいます。 これを「再帰呼出し」といいます。 再帰呼出しのとき、そのどの呼び出しにおいてもパラメータは別物なので、このような計算結果になります。

再帰呼出しは、この例の階乗(factorial)計算に限らず、使えるケースが少なくありません。

まとめ

  • トップレベルのメソッドはCの関数(あるいは他の言語の関数や手続き)のように使うことができる
  • メソッドにはパラメータをつけることができる。 パラメータはそのメソッドの中でのみ有効
  • パラメータはメソッド名直後(から次の)まで。 括弧は略すことができる。 そのときは左括弧の代わりに半角空白を入れる
  • メソッドを再帰呼出しすることができる
  • if - elsif - else - end が使える

2023

単項マイナスと構文解析

1 minute read

単項マイナスとは 単項マイナスと括弧 括弧なし単項マイナスを許容する場合のBNF calcの場合

Raccライブラリと構文解析

3 minute read

パーサ・ジェネレータとは 少し複雑な文法 四則(加減乗除)計算のBNF Racc で実装 クラス定義、BNFの記述部分 ヘッダー、インナー、フッター コンパイルと実行 演算子の優先順位と結合における左右の優先順位 まとめ

StrScanライブラリと字句解析

less than 1 minute read

StrScanライブラリのドキュメント 字句解析とは StrScanライブラリ StrScanライブラリを使った字句解析 実例

Gem

1 minute read

lbtというgemを作って公開してみた lbtはどんなgemか ファイルの配置 lbt.gemspec Rakefile gemのビルド RubyGems.orgへのアップロード 補足・・rake/gempackagetaskサブライブラリについて

Encoding

1 minute read

文字列のエンコーディングに頭を悩ませることはほとんどなくなりました。 なぜなら、どのアプリ、システムもUTF-8を使うようになったからです。 Rubyでもエンコーディングの問題が起こることはまず無いでしょう。 ですが、今回はエンコーディングの考え方を整理してみたいと思います。

Thread

less than 1 minute read

Fiberを書いたときから、次はスレッドを書こうと思っていましたが、時間がかかってしまいました。 その理由は、期待したとおりのスレッドの効果がなかったためです。 今回はそのことを書きますが、これはRubyのスレッドの抱えている問題なのか、自分のやり方が悪いのかははっきりしていません。

Fiber

1 minute read

Fiberは「ノンプリエンプティブな軽量スレッド」とRubyのマニュアルに記載されています。

RDoc

less than 1 minute read

今回はRubyプログラムから自動的にドキュメントを作成するRDocについて書きたいと思います。 私はこのことについて、エキスパートではありません。 この記事も、初心者の体験談だと考えてください。

Back to Top ↑

2022

Ruby/GTK4

5 minute read

Ruby/Gtkの記事を先日書いたときに、「これはかなり使える」という手応えを感じたので、WordBook(Railsで作った単語帳プログラム)のGTK 4版を作りました。 プログラムは「徒然なるままにRuby」のGitHubレポジトリに置いてあります。 レポジトリをダウンロードし、ディレクトリ_example/...

Shoes – Rubyとグラフィック

5 minute read

Rubyはグラフィックについて弱い印象があります。 しかし、グラフィックはデバイスに関することなので、言語そのものには直接の関係はないはずで、あるとすればライブラリです。 今後グラフィック関係のgemが開発されることに期待しましょう。

Rails7 テスト

5 minute read

前回作ったWordbook(リソースフル)のテストを書いてみます。 RailsのテストはminitestをRails用に拡張したものです。

Rails7 モデルとデータベース

2 minute read

今回はRailsにおけるデータの作成と保存、そして変更について説明します。 そのベースになるモデルとデータベースの話から始め、appendとchangeの動作について詳しく説明します。

Rails7とBootstrap

2 minute read

一般に、HTMLは文書の構造を表し、CSSはその体裁(見栄え)を表します。 Railsは最終的にCSSを含むHTML文書を出力するので、この2つについての理解が必須です。 この記事ではとくにCSSの人気ライブラリであるBootstrapを紹介します。 BootstrapはJavascriptも含んでいます。

Rails7のインストール

2 minute read

Rubyの最も人気のあるアプリケーションであるRuby on Railsを取り上げようと思い、書き始めました。 予想してはいましたが、相当な分量になってしまいました。 そのため、何回かに分けて記事にすることにします。 また、対象となる読者のレベルをどうしようかと考えましたが、「徒然Ruby」が基礎的な内容から始ま...

GemとBundler

1 minute read

Rubyのライブラリ管理システムのRubygemsとコマンドgemおよびbundlerについて説明します。

minitest(3)モックの詳細

2 minute read

minitestについて連続して2回書いてきました。 「minitestはドキュメントが少ない」という人がいますが、私も同感です。 例えば、モックとスタブの説明も少ないです。 そこで、今回はmock.rbのソースコードを参考に、モックの私的ドキュメントを書いてみました。 あくまで私個人の考えであり、minites...

minitest(1)テストとは

2 minute read

アプリ作成の記事でminitestを使いました。 今回はminitestについて、また一般にテストについて、私の考えを書こうと思います。

public、private、protected

2 minute read

今回はメソッドの呼び出し制限ついて説明します。 呼び出し制限にはpublic、private、protectedの3つがあります。

アプリ制作、インストール、テスト

1 minute read

2023/10/29 追記:この記事は新しく書き直しました。 古い記事で使っていたGitHubのCalcが大幅にアップデートされたためです。 そこで、この記事に合うようなプログラムsimple_calcを新たに作りました。 このプログラムは本レポジトリの_example/simple_calcにあります。

case文

2 minute read

if〜elsif〜・・・〜else〜endは皆さん良く使うでしょうか? これは場合分けで良く使われる方法です。 これと同様の制御構造にcase文があります。 Cのswitch文に似ていますが、より強力な機能を持っています。 if-else-endよりも高い能力があるといえます。

Lambda

1 minute read

Procオブジェクトを生成するメソッドlambdaについて説明します。

Proc オブジェクト

2 minute read

今回はブロックを一般化したオブジェクトProcを説明します。

モジュール

less than 1 minute read

モジュールには名前空間とミックスイン(Mix-in)の2つの機能があります。 ここではミックスインについて説明します。

Kernelモジュール

1 minute read

Kernelモジュールのメソッドはどこでも使うことができます。 そのメソッドの中には便利で有用なものが多いです。

便利なメソッド

1 minute read

ここでは私が便利だと思ったメソッドを紹介します。

文字列と正規表現

2 minute read

文字列は最も使うオブジェクトのひとつです。 特にウェブ・アプリケーションでは、コンテンツだけでなくHTMLのタグやCSSを含めすべてが文字列です。 Rubyは文字列オブジェクトのメソッドが充実しており、またパターンマッチのための正規表現も充実しています。

配列

2 minute read

配列は、どのプログラミング言語にもあると思います。 複数の要素を一括して扱うことができるのが配列です。 Rubyの配列はメソッドが充実しているので、プログラムを効率的、機能的に書くのに役立ちます。

トップレベルのメソッド

1 minute read

今回はメソッド定義です。 メソッド定義はRubyの核心ですが、今回はトップレベルに限って説明します。 この限定によって、内容はかなり易しくなっています。

ブロックとイテレータ

less than 1 minute read

ブロックはRubyの特長です。 ブロックのおかげで記述が非常にすっきりと分かりやすくなります。 今回はブロックをイテレータの本体として使う方法を説明します。

整数

less than 1 minute read

ここではRubyの最も基本的なオブジェクトである整数について説明します。

Hello world

less than 1 minute read

「徒然なるままに」をネットで調べてみると、「することもなく、手持無沙汰なのにまかせてという意味」とありました。 まさに、自分の現状を言い当てた言葉。 しかも、ブログに書くネタもなかなか思いつかない日々。

Back to Top ↑