単項マイナスと構文解析
単項マイナスとは 単項マイナスと括弧 括弧なし単項マイナスを許容する場合のBNF calcの場合
今回はRailsの慣例に沿った形でWordbookを作り直します。
Railsには「Convention Over Configuration」(設定より規約が優先)という哲学があります。 「規約」とは「プログラミングの約束事」ですが、「プログラミングの慣例」あるいは「習慣」と言う方が合っているかもしれません。 というのは、この「規約」というのは「絶対に守らなければいけないルール」ではなく、「Railsが勧めるより良いプログラミングの方法」のことなのです。
そのひとつに、コントローラのアクションは7つにまとめることができる、というのがあります。
Railsでは、「RESTful」(レストフル)なウェブアクセスでは、アクションをこの7つにまとめることができる、としています。 RESTfulは形容詞で「RESTな」ということです。 では、RESTとは何かというと、それは「Representational State Transfer」を短くしたもので、ウェブ・インターフェースのアーキテクチャスタイルです。 これでは説明にならないと思うので、具体的に説明すると次の4つを持つスタイルです
これから、RESTfulというのは私達がブラウザでウェブにアクセスしているスタイルのことを概念的にまとめたものだと分かると思います。 ウィキペディアに情報がありますので、参考にしてください。
RailsではRESTfulなアクセスは上記の7つのアクションにまとめることができるから
ということなのです。
上記の7つのアクションの構成は、前回作ったwordbookの構成に似ていますが、名前が違っていました。
Railsの慣例によるアクション名 | 前回wordbookのアクション名 |
---|---|
new | append |
edit | change |
destroy | exec_delete |
delete | |
search |
deleteとsearchが前のwordbookにありましたが、これはRailsの慣例アクション名にはありません。
今回はこの慣例に合うようにWordbookを作り直します。 ただ、次の点は慣例と異なります。
それでは、WordBookの新版を作りましょう。 ディレクトリ名を「word_book_rails_resources」とします。 ディレクトリ、コントローラ、モデルを作り、データベースのマイグレーションをします。
$ rails new word_book_rails_resources -c bootstrap
... ... ...
$ cd word_book_rails_resources
$ ./bin/rails generate controller Words index show new create edit update delete search
... ... ...
$ ./bin/rails generate model Word en:string jp:string note:text
... ... ...
$ ./bin/rails db:migrate
... ... ...
モデルのフィールドには「英単語」「日本語訳」に加えて「備考」(note)を作りました。 フィールドタイプのstringは短い文字列(通常一行)で、textは複数行に渡るような文字列です。 備考には例文や解説を書くことを想定しています。
モデルのバリデーションは英単語と日本語訳に設定します。 備考については空欄でも構わないとします。
class Word < ApplicationRecord
validates :en, presence: true, format: {with: /[a-zA-Z]+/}, uniqueness: true
validates :jp, presence: true
end
/config/routes.rb
を編集します。
Rails.application.routes.draw do
root "words#index"
get "words/search"
resources :words
end
rootとsearchは個別のルーティングを書いておきます。
Railsの7つのアクションは「resources」メソッドでルーティングを定義します。
これはRailsが用意した「便利な工夫」のひとつで、これだけで7つのルーティングが記述できます。
このとき、それぞれのルーティングがどうなっているかは、./bin/rails routes
コマンドで確認できます。
$ ./bin/rails routes
Prefix Verb URI Pattern Controller#Action
root GET / words#index
words_search GET /words/search(.:format) words#search
words GET /words(.:format) words#index
POST /words(.:format) words#create
new_word GET /words/new(.:format) words#new
edit_word GET /words/:id/edit(.:format) words#edit
word GET /words/:id(.:format) words#show
PATCH /words/:id(.:format) words#update
PUT /words/:id(.:format) words#update
DELETE /words/:id(.:format) words#destroy
... ... ...
左の列「Prefix」に、「_path」をつけるとパスを返すメソッドが得られます。
root_path #=> /
words_search_path #=> /words/search
words_path #=> /words
このような形で他アクションへのメソッドも得られます。
createアクションはアドレスがindexアクションと同じなのでwords_path
でPOSTメソッドを使えばアクセスできます。
同様にupdateアクションはword_path
をPATCHまたはPUTメソッドで、destroyアクションはword_path
をDELETEメソッドでアクセスすることによりアクセスできます。
7つのルーティングがresources
メソッド1つで書けるところが、負担軽減になっています。
このようなルーティングを「リソースフル・ルーティング」と呼んでいます。
なお、「リソース」というのはウェブサーバで扱っているデータのことで、例えばWordインスタンスの表すデータはリソースです。
レイアウト/app/views/layouts/application.html.erb
は前回のWordbookと同様ですが、画面幅は少し広めにしました。
<!DOCTYPE html>
<html>
<head>
<title>WordBookRailsResources</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_include_tag "application", "data-turbo-track": "reload", defer: true %>
</head>
<body>
<div class="container">
<div class="col-lg-10 col-xl-8 mx-auto">
<%= render "navbar" %>
<%= render "flash" %>
<%= yield %>
</div>
</div>
</body>
</html>
ナビゲーションバー/app/views/words/_navbar.html.erb
も前回とほぼ同様ですが次の2点が異なります。
<nav class="navbar navbar-expand-lg navbar-light" style="background-color: #e3f2fd;">
<div class="container-fluid">
<a class="navbar-brand" href="/">Wordbook</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
<li class="nav-item">
<%= link_to "追加", new_word_path, style: "text-decoration: none;", class: "nav-link" %>
</li>
<li class="nav-item">
<% if action_name == "show" && @word %>
<%= link_to "変更", edit_word_path(@word), style: "text-decoration: none;", class: "nav-link" %>
<% else %>
<a class="nav-link disabled" href="#">変更</a>
<% end %>
</li>
<li class="nav-item">
<% if action_name == "show" && @word %>
<%= link_to "削除", @word, style: "text-decoration: none;", class: "nav-link", data: {turbo_method: :delete, turbo_confirm: "Are you sure?"} %>
<% else %>
<a class="nav-link disabled" href="#">削除</a>
<% end %>
</li>
</ul>
<%= form_with url: words_search_path, method: :get, class: "d-flex" do |form| %>
<%= form.search_field :search, placeholder: "検索", class: "form-control me-2" %>
<%= form.submit "検索", class: "btn btn-outline-success text-nowrap" %>
<% end %>
</div>
</div>
</nav>
13、20行目に<% if action_name == "show" %>
があります。
action_name
はRailsのメソッドで、そのときのアクション名を文字列で返します。
したがって、if節はアクションがshowのときだけ実行され、それ以外はelse節(リンクdisable)になります。
また、削除リンクはdata: {turbo_method: :delete, turbo_confirm: "Are you sure?"}
により、HTTPメソッドがdeleteになり、「Are you sure?」の確認ダイアログが表示されます。
前回のwordbookではフォームの送信ボタンが削除のきっかけになっていましたが、今回はナビゲーションバーの「削除」メニューがきっかけになっています。
また、リンク先が@word
となっています。
リソースフル・ルーティングでは@word
とword_path(@word)
は同じパスを指します。
下から7〜4行目が検索部分で、form_with
によるフォーム送信が埋め込まれています。
「検索」ボタンを押すとsearchアクションに飛ぶようにリンク先がwords_search_path
メソッドで与えられています。
フラッシュは前回と同じです。
<% flash.each do |name, msg| %>
<% if name == "success" %>
<%= content_tag :div, msg, class: "text-success" %>
<% elsif name == "alert" %>
<%= content_tag :div, msg, class: "text-danger" %>
<% end %>
<% end %>
indexアクションは初期画面です。 Wordbookの使い方を表示します。
コントローラでは特にやることはありません。
def index
end
ビューapp/views/words/index.html.erb
は次のようになります。
<h1 class="text-center">単語帳</h1>
<h5 class="my-2">単語帳の使い方</h5>
<ul class="list-group my-2">
<li class="list-group-item">Wordbook: 初期画面に戻ります</li>
<li class="list-group-item">追加: 単語を追加します</li>
<li class="list-group-item">検索: 単語を検索しマッチした単語を表示します</li>
</ul>
<p>
検索にRubyの正規表現を使うことができます。
各単語に対して「英単語」「日本語訳」「備考」を書き、保存することができます。
「備考」は複数行のテキストが可能なので、例文や解説などを書くのに適しています。
</p>
<p>
単語の表示、変更、削除は次のようにしてください。
なお「単語の表示」または「表示画面」とは、ひとつの単語についてその日本語訳と備考を表示すること、またはその画面です。
検索結果の画面では備考は表示されません。
</p>
<ul class="list-group my-2">
<li class="list-group-item">表示: 検索後の一覧において、各項目の左にあるボタンをクリック</li>
<li class="list-group-item">変更: 表示画面から変更メニューをクリック</li>
<li class="list-group-item">削除: 表示画面から削除メニューをクリック</li>
</ul>
ナビゲーションバーの入力枠に正規表現を入れ、検索ボタンをクリックすることにより、/words/search
にgetメソッドでアクセスします。
これはsearchアクションにルーティングされます。
def search
@search_word = params[:search]
if @search_word == ""
flash.now[:alert] = "検索ワードは入力必須です"
render html: "", status: :unprocessable_entity
end
begin
pattern = Regexp.compile(@search_word)
rescue RegexpError
flash.now[:alert] = "正規表現に構文エラーがあります"
render :index, status: :unprocessable_entity
else
@words = Word.all.select{|word| word[:en] =~ pattern}.sort{|w1,w2| w1[:en] <=> w2[:en]}
end
end
検索ワードはsearchという名前で送られるので、params[:search]
で取り出すことができます。
searchアクションの内容は、前回のWordbookのlistアクションとほぼ同じです。
ビュー/app/views/words/search.html.erb
は次のようになります。
<h1 class="my-2">単語検索結果</h1>
<p>検索ワード: <%= @search_word %></p>
<% if @words %>
<table class="table table-bordered">
<thead>
<tr>
<th scope="col">英語</th>
<th scope="col">日本語</th>
</tr>
</thead>
<tbody>
<% @words.each do |word| %>
<tr>
<td><%= link_to word[:en], word %></td>
<td><%= word[:jp] %></td>
</tr>
<% end %>
</tbody>
</table>
<% end %>
ここでは、英語と日本語訳のみを表にして表示します。
英単語はshowアクションへのリンクになっています。
word
がshowアクションへのリンクです。
このリンクには該当の単語のid(データベースの通し番号)が挿入されます。
showアクションはid番号を用いてデータベースからWordモデルを取り出します。
def show
begin
@word = Word.find(params[:id])
rescue ActiveRecord::RecordNotFound
@word = nil
flash.now[:alert] = "データベースにはid=#{params[:id]}のデータは登録されていません"
end
end
search画面のリンクからshowアクションに遷移した場合はエラーになることはありません。
クライアント側が適当なid番号で「words/id番号
」をgetでアクセスした場合にはエラーの発生する可能性があります。
そのためrescueを使ったエラー処理を入れておきました。
ビュー/app/views/words/show.html.erb
は次のようになります。
<% if @word %>
<ul class="list-group my-2">
<li class="list-group-item"><%= @word.en %></li>
<li class="list-group-item"><%= @word.jp %></li>
<li class="list-group-item"><%= @word.note %></li>
</ul>
<% end %>
showでは英単語、日本語訳に加え備考(@word.note
)も表示します。
ナビゲーションバーの「追加」をクリックすると/words/new
にgetメソッドでアクセスします。
そして、newアクションにルーティングされます。
newコントローラはWordモデルを生成して@wordに代入します。
def new
@word = Word.new
@submit = "作成"
end
ビュー/app/views/words/new.html.erb
は次のようになります。
<h1 class="my-2">単語登録</h1>
<%= render "form" %>
画面の組み立てはformパーシャルが行います。
<%= form_with model: @word do |form| %>
<div>
<%= form.label :en, "英単語", class: "form-label" %>
<%= form.text_field :en, value: @word.en, class: "form-control" %>
<% @word.errors.full_messages_for(:en).each do |message| %>
<div class="text-danger"><%= "DB: 英単語は空欄にできません" if message == "En can't be blank" %></div>
<div class="text-danger"><%= "DB: 英文字を入力してください" if message == "En is invalid" %></div>
<div class="text-danger"><%= "DB: すでに同名の単語が登録されています" if message == "En has already been taken" %></div>
<% end %>
</div>
<div>
<%= form.label :jp, "日本語訳", class: "form-label" %>
<%= form.text_field :jp, value: @word.jp, class: "form-control" %>
<% @word.errors.full_messages_for(:jp).each do |message| %>
<div class="text-danger"><%= "DB: 日本語訳は空欄にできません" if message == "Jp can't be blank" %></div>
<% end %>
</div>
<div>
<%= form.label :note, "備考", class: "form-label" %>
<%= form.text_area :note, value: @word.note, class: "form-control" %>
<% @word.errors.full_messages_for(:jp).each do |message| %>
<div class="text-danger"><%= message %></div>
<% end %>
</div>
<div class="my-2">
<%= form.submit @submit, class: "btn btn-primary" %>
</div>
<% end %>
ルーティングがリソースフルである場合は、form_with
にモデルを設定すればurlは省略できます。
送信ボタンを押すとcreateアクションにアクセスします。
「備考」の入力枠はform.text_area
で作ります。
複数行のテキストを想定した入力フォームです。
createアクションはコントローラのみでビューはありません。
def create
@word = Word.new(word_params)
if @word.save
flash[:success] = "単語を保存しました"
redirect_to @word, status: :see_other
else
flash.now[:alert] = "単語を保存できませんでした"
render :new, status: :unprocessable_entity
end
end
private
def word_params
params.require(:word).permit(:en, :jp, :note)
end
プライベートメソッドword_params
はクライアントからのデータを調べ、必要なものだけを取り出します。
この仕組みはparams
、require
、permit
の3つのメソッドで構成されています。
この仕組みはストロング・パラメータと呼ばれ、仮に不正なデータが送られたとしてもそれを除去することができます。
createメソッドでWord.new(word_params)
としても安全です。
これを使わず`Word.new(params)とするとサーバ側で予期していないデータを保存しようとする可能性があり、エラーになったり、何らかの問題を引き起こす可能性があります。
Wordbookではストロングパラメータを使わなくてもほとんど危険はありませんが、ユーザ登録の仕組みを持つサーバでは脆弱性が発生することがあります。
例えば、ユーザモデルUserが3つのフィールドname、email、adminを持っていて、最後のadminは管理者権限を表し、true=admin
、nil|false=not admin
だとします。
newアクションのビューではnameとemailのみをデータ送信するようになっているとします。
通常なら@user=User.new(params)
でnameとemailのみ代入され、admin=nilとなるのですが、
悪意のあるユーザがPOSTデータを改ざんしname、emailに加えadmin=trueを送ってきたとすると、新規ユーザは管理者になってしまいます。
ストロングパラメータがパラメータをnameとemailに限定すれば、このような危険は無くなるというわけです。
createアクションでは、単語登録できればshowにリダイレクト、失敗したら再度newの画面を表示します。
editアクションはshowアクションから遷移される前提です。
showアクションの画面ではナビゲーションバーの「変更」リンクが有効になります。
/words/:id/edit
にアクセスがあるとeditアクションにルーティングされ、:id
のところの数字がパラメータとしてparams[:id]
にセットされます。
def edit
begin
@word = Word.find(params[:id])
rescue ActiveRecord::RecordNotFound
@word = nil
flash[:alert] = "データベースにはid=#{params[:id]}のデータは登録されていません"
redirect_to words_path, status: :see_other
end
@submit = "変更"
end
show画面から遷移すればWord.find(params[:id])
がエラーになることはありませんが、ユーザがURLを作ってアクセスすると、そうとも限りません。
そこで、rescueを使ったエラーの捕捉をしています。
ビューは次のようになります。
<h1 class="my-2">単語の変更</h1>
<%= render "form" %>
newと共有しているformパーシャルを使います。
editの場合は送られてきたデータによってフォーム入力枠に値が入った状態から編集することができます。
編集が終わるとupdateアクションに遷移します。
newではcreateアクションへの遷移でした。
どこでcreateとupdateを区別しているかと言うと、@wordのidフィールドがnilか数字かの違いです。
この判断はform_with
メソッドがしてくれるので、プログラマーが気にする必要はありません。
updateアクションはコントローラのみでビューはありません。
def update
@word = Word.find(params[:id])
if @word.update(word_params)
redirect_to @word, status: :see_other
else
flash.now[:alert] = "単語「#{@word.en}」は変更できませんでした"
render :edit, status: :unprocessable_entity
end
end
アップデートができたらshowにリダイレクト、失敗したらedit画面を再表示します。
@word
だけで/words/:id
にリダイレクトできます。
word_path(@word)
よりも短い@word
だけで同じリンク先を生成してくれるは、リソースフル・ルーティングのさらなる恩恵です。
show画面ではナビゲーションバーの「削除」リンクが使えるようになります。 それをクリックするとdestroyアクションに遷移します。 destroyアクションはコントローラだけでビューはありません。
def destroy
@word = Word.find(params[:id])
if @word == nil
flash[:alert] = "単語#{@en}は未登録のため削除できません"
else
begin
@word.destroy
rescue
flash[:alert] = "単語#{@en}を削除できませんでした"
else
flash[:success] = "単語を削除しました"
end
redirect_to words_path, status: :see_other
end
end
削除ができてもできなくてもINDEX画面にリダイレクトします。 クライアント側はフラッシュ・メッセージによって削除できたかどうかを知ることができます。
コマンドラインから起動します。
$ ./bin/rails server
ブラウザを起動しhttp://localhost:3000
にアクセスするとWordbookの初期画面が現れます。
railsを終了するには、コマンドラインからCTRL-Cを入力します。
前回のWordbookと比べ、大きな差はないものの、リソースフル・ルーティングを使ったおかげで楽をした部分がありました。 また、Railsの慣例に従っているので、メンテナが変わっても分かりやすいはずです。 そのような保守管理の意味でも慣例を守るのは重要なことです。
Wordbookはシンプルで分かりやすいと思います。 実際のウェブの開発はもっと複雑でデータベース・テーブルも複数になり、それらが関係しあっていることもあります。 そのようなテーブル間の関係をRailsはサポートしているのですが、今回はそこまでは踏み込みませんでした。 詳しいことは「Rails Guide」を参照してください。
また、ソースコードはGitHubの_example/word_book_rails_resources
にありますので、
必要な方はダウンロードまたはクローンしてお使いください。
単項マイナスとは 単項マイナスと括弧 括弧なし単項マイナスを許容する場合のBNF calcの場合
パーサ・ジェネレータとは 少し複雑な文法 四則(加減乗除)計算のBNF Racc で実装 クラス定義、BNFの記述部分 ヘッダー、インナー、フッター コンパイルと実行 演算子の優先順位と結合における左右の優先順位 まとめ
StrScanライブラリのドキュメント 字句解析とは StrScanライブラリ StrScanライブラリを使った字句解析 実例
lbtというgemを作って公開してみた lbtはどんなgemか ファイルの配置 lbt.gemspec Rakefile gemのビルド RubyGems.orgへのアップロード 補足・・rake/gempackagetaskサブライブラリについて
文字列のエンコーディングに頭を悩ませることはほとんどなくなりました。 なぜなら、どのアプリ、システムもUTF-8を使うようになったからです。 Rubyでもエンコーディングの問題が起こることはまず無いでしょう。 ですが、今回はエンコーディングの考え方を整理してみたいと思います。
Fiberを書いたときから、次はスレッドを書こうと思っていましたが、時間がかかってしまいました。 その理由は、期待したとおりのスレッドの効果がなかったためです。 今回はそのことを書きますが、これはRubyのスレッドの抱えている問題なのか、自分のやり方が悪いのかははっきりしていません。
Fiberは「ノンプリエンプティブな軽量スレッド」とRubyのマニュアルに記載されています。
今回はRubyプログラムから自動的にドキュメントを作成するRDocについて書きたいと思います。 私はこのことについて、エキスパートではありません。 この記事も、初心者の体験談だと考えてください。
Ruby/Gtkの記事を先日書いたときに、「これはかなり使える」という手応えを感じたので、WordBook(Railsで作った単語帳プログラム)のGTK 4版を作りました。 プログラムは「徒然なるままにRuby」のGitHubレポジトリに置いてあります。 レポジトリをダウンロードし、ディレクトリ_example/...
今回はGTK 3とGTK 4をRubyで使うライブラリについて書きたいと思います。
今回もRubyとGUIのトピックです。 Glimmerを取り上げます。
Rubyはグラフィックについて弱い印象があります。 しかし、グラフィックはデバイスに関することなので、言語そのものには直接の関係はないはずで、あるとすればライブラリです。 今後グラフィック関係のgemが開発されることに期待しましょう。
Rails7におけるシステムテストについて書きます。
前回作ったWordbook(リソースフル)のテストを書いてみます。 RailsのテストはminitestをRails用に拡張したものです。
今回はRailsの慣例に沿った形でWordbookを作り直します。
今回はWordBookの検索と削除についてです。
今回はRailsにおけるデータの作成と保存、そして変更について説明します。 そのベースになるモデルとデータベースの話から始め、appendとchangeの動作について詳しく説明します。
一般に、HTMLは文書の構造を表し、CSSはその体裁(見栄え)を表します。 Railsは最終的にCSSを含むHTML文書を出力するので、この2つについての理解が必須です。 この記事ではとくにCSSの人気ライブラリであるBootstrapを紹介します。 BootstrapはJavascriptも含んでいます。
Rubyの最も人気のあるアプリケーションであるRuby on Railsを取り上げようと思い、書き始めました。 予想してはいましたが、相当な分量になってしまいました。 そのため、何回かに分けて記事にすることにします。 また、対象となる読者のレベルをどうしようかと考えましたが、「徒然Ruby」が基礎的な内容から始ま...
Rubyのライブラリ管理システムのRubygemsとコマンドgemおよびbundlerについて説明します。
minitestについて連続して2回書いてきました。 「minitestはドキュメントが少ない」という人がいますが、私も同感です。 例えば、モックとスタブの説明も少ないです。 そこで、今回はmock.rbのソースコードを参考に、モックの私的ドキュメントを書いてみました。 あくまで私個人の考えであり、minites...
今回もminitestの話です。 mockとstubに焦点をあて説明します。
アプリ作成の記事でminitestを使いました。 今回はminitestについて、また一般にテストについて、私の考えを書こうと思います。
今回はメソッドの呼び出し制限ついて説明します。 呼び出し制限にはpublic、private、protectedの3つがあります。
今回は特異メソッド、特異クラス定義、名前空間、モジュール関数について説明します。
2023/10/29 追記:この記事は新しく書き直しました。 古い記事で使っていたGitHubのCalcが大幅にアップデートされたためです。 そこで、この記事に合うようなプログラムsimple_calcを新たに作りました。 このプログラムは本レポジトリの_example/simple_calcにあります。
if〜elsif〜・・・〜else〜endは皆さん良く使うでしょうか? これは場合分けで良く使われる方法です。 これと同様の制御構造にcase文があります。 Cのswitch文に似ていますが、より強力な機能を持っています。 if-else-endよりも高い能力があるといえます。
Procオブジェクトを生成するメソッドlambdaについて説明します。
今回はブロックを一般化したオブジェクトProcを説明します。
ブロック付きメソッドの作り方を説明します。
モジュールには名前空間とミックスイン(Mix-in)の2つの機能があります。 ここではミックスインについて説明します。
クラスの親子関係
Rubyの演算子とその再定義について書きます。
今回からクラスとインスタンスを定義、生成する方法を説明します
Kernelモジュールのメソッドはどこでも使うことができます。 そのメソッドの中には便利で有用なものが多いです。
ここでは私が便利だと思ったメソッドを紹介します。
実数
今回はシンボルとハッシュについて説明します。
文字列は最も使うオブジェクトのひとつです。 特にウェブ・アプリケーションでは、コンテンツだけでなくHTMLのタグやCSSを含めすべてが文字列です。 Rubyは文字列オブジェクトのメソッドが充実しており、またパターンマッチのための正規表現も充実しています。
配列は、どのプログラミング言語にもあると思います。 複数の要素を一括して扱うことができるのが配列です。 Rubyの配列はメソッドが充実しているので、プログラムを効率的、機能的に書くのに役立ちます。
今回の目標はインスタンスです。 インスタンスを説明するために、ローカル変数と文字列オブジェクトを事前に扱います。
今回はメソッド定義です。 メソッド定義はRubyの核心ですが、今回はトップレベルに限って説明します。 この限定によって、内容はかなり易しくなっています。
ブロックはRubyの特長です。 ブロックのおかげで記述が非常にすっきりと分かりやすくなります。 今回はブロックをイテレータの本体として使う方法を説明します。
ここではRubyの最も基本的なオブジェクトである整数について説明します。
「徒然なるままに」をネットで調べてみると、「することもなく、手持無沙汰なのにまかせてという意味」とありました。 まさに、自分の現状を言い当てた言葉。 しかも、ブログに書くネタもなかなか思いつかない日々。