コース目次 / 第3章

成果物 — 1行日記

毎日1行だけ書きためて、あとから読み返せる日記CLIを作ります。

第3章 / 全5章目安 約50分この章のゴール: ruby nikki.rb で1行書けて、ruby nikki.rb list で読み返せる
お使いのエディタ
ファイル操作が切り替わります

いよいよ道具を作ります。1日1行だけ書く日記です。

今日のゴール

こうなります
$ ruby nikki.rb
今日の1行> 直島でレンタサイクルを借りた
書きました。これで 1 行になりました。

$ ruby nikki.rb list
2026-08-01  直島でレンタサイクルを借りた

1日1行しか書けないのがこの道具の設計です。書くことが思いつかない日でも、1行なら書けます。

1. ミニ解説: 今日使う道具

書き方 何をするか
ARGV コマンドのうしろに付けた言葉の一覧。ruby nikki.rb list なら ARGV[0] が "list"
File.open(名前, "a:UTF-8") ファイルを追記で開く。a は append(足す)
File.readlines(名前) ファイルを1行ずつの配列にして読む
def … end 自分でコマンドを作る。何度も使うところに名前を付ける
line.chomp.split("\t") 行末の改行を落として、タブで2つに分ける

date も File も、Rubyに最初から入っています。何もインストールしません。このコースで gem install は一度も出てきません。

2. 書く

nikki.rb を作って、そのまま書き写します。少し長いですが、上から順に読めるはずです。

nikki.rb
# はるとの1行日記
#
#   ruby nikki.rb        今日の1行を書く
#   ruby nikki.rb list   これまでの分を読む

require "date"

NIKKI = "nikki.txt"

# 日本語を、Mac でも Windows でも同じように読み書きするための指定。
$stdin.set_encoding("UTF-8")

def yomu
  return [] unless File.exist?(NIKKI)

  File.readlines(NIKKI, encoding: "UTF-8")
end

if ARGV[0] == "list"
  nikki = yomu

  if nikki.empty?
    puts "まだ1行も書いていません。"
    exit
  end

  nikki.each do |line|
    hizuke, honbun = line.chomp.split("\t")
    puts "#{hizuke}  #{honbun}"
  end
else
  print "今日の1行> "
  honbun = $stdin.gets.to_s.chomp

  if honbun.empty?
    puts "なにも書かれていないので、やめておきます。"
    exit
  end

  # 日付は今日のもの。TODAY が決まっていればそれを使う(同じ結果を出したいときのため)。
  hizuke = ENV["TODAY"] || Date.today.strftime("%Y-%m-%d")

  File.open(NIKKI, "a:UTF-8") do |f|
    f.puts "#{hizuke}\t#{honbun}"
  end

  puts "書きました。これで #{yomu.size} 行になりました。"
end

読みどころが3つあります

(1) def yomu — 自分で作った小さなコマンド

日記を読む処理に名前を付けました。まだファイルが無ければ空の配列を返すので、呼ぶ側は「ファイルがあるかどうか」を気にしなくて済みます。

(2) $stdin.set_encoding("UTF-8") と "a:UTF-8"

この2つは日本語のためのおまじないです。これを書いておくと、MacでもWindowsでも、日本語が同じように読み書きされます。
書かないと、環境によってはEncoding::InvalidByteSequenceError という長いエラーで止まります。おまじないと言いましたが、実際にそうなることを確かめた上で入れてあります。

(3) ENV["TODAY"] || Date.today...

|| は「左がだめなら右」。TODAY が外から決まっていればそれを使い、無ければ今日の日付という意味です。ふだんは何もしなくて構いません。「昨日の分をあとから足したい」ときに効きます。

3. 書いてみる

ターミナル派の方

ターミナル
cd ~/Desktop/nikki

行頭の $ は「ここからコマンド」という目印です。$ は打たないでください。

VS Codeのターミナルターミナル
ruby nikki.rb

行頭の $ は「ここからコマンド」という目印です。$ は打たないでください。

今日の1行> と出るので、今日あったことを1行書いて Enter。

こう出る
今日の1行> 直島でレンタサイクルを借りた
書きました。これで 1 行になりました。

フォルダに nikki.txt ができています。これがあなたのデータです。

4. 読み返す

VS Codeのターミナルターミナル
ruby nikki.rb list

行頭の $ は「ここからコマンド」という目印です。$ は打たないでください。

こう出る
2026-08-01  直島でレンタサイクルを借りた

もう何日か書いてから、もう一度 list してみてください。日記らしくなってきます。

こわしてみる

3つ試してください。どれも壊れないように書いてあります。

(1) 何も書かずに Enter

こう出る
今日の1行> 
なにも書かれていないので、やめておきます。

空行が日記に混ざりません。

(2) まだ1行も書いていない状態で list

nikki.txt を一時的に別名にしてから試すと分かります。

こう出る
まだ1行も書いていません。

エラーではなく、案内が出ます。これは def yomu の中の return [] unless File.exist?(NIKKI) が効いているためです。

(3) 昨日の分を足す

VS Codeのターミナルターミナル
TODAY=2026-07-31 ruby nikki.rb

行頭の $ は「ここからコマンド」という目印です。$ は打たないでください。

日付を指定して書けます(Windowsの PowerShell では $env:TODAY="2026-07-31"; ruby nikki.rb のように打ちます)。

ハマったら

「Encoding::InvalidByteSequenceError」と出る

$stdin.set_encoding("UTF-8") の行か、File.open の "a:UTF-8" のどちらかが抜けています。この2つは日本語を扱うための必須の部品です。写し忘れていないか確かめてください。

list に何も出ない

nikki.txt が nikki.rb と同じフォルダにあるか確かめてください。VS Code の左側で、nikki.rb と nikki.txt が同じ高さに並んでいれば正解です。ls を打って、両方出てくれば正解です。

別のフォルダから ruby nikki.rb を実行すると、そちらに新しい nikki.txt ができます。いつも同じフォルダで実行してください。

「undefined method」と出る

打ち間違いです。エラーの1行目にメソッド名とファイルの行番号が出ているので、その行を見てください。Rubyは Did you mean? と近い名前を教えてくれることもあります。

ZIPで戻したい

このページの下のZIPは、この章を終えた状態のフォルダです。解凍して、その中で作業を続けられます。自分で書き換えた部分は消えてしまうので、先に自分のファイルを別の場所へ待避してから使ってください。

こうなっていればOK

うまくいかないときは、この章の完成ファイル一式(ZIP)をダウンロードして続きから進めても大丈夫です。

卒業まであと1章です。

この章はまだ完了していません。