人生で影響を受けた本100冊。
https://qiita.com/kaizen_nagoya/items/16af53acbb147a94172e
9番目の本のプログラマ編。
10. 卵の緒
新潮文庫, 2007/6, 瀬尾 まいこ

https://www.amazon.co.jp/dp/410129772X/
https://bookmeter.com/books/578950
https://booklog.jp/item/1/410129772X
卵の緒と7's bloodの2話。淡々とした日常会話。非日常が混ざる。すばらしい作品に出会えたことに感謝。世の中には卵の緒のお母さんのようなすごい人がきっといるに違いない。卵の緒では卵生だという話に実子でないことが想像できた。7's bloodでは異母姉弟の暮らし。純粋な不思議ちゃんが登場人物。瀬尾まいこが「私には父親がいない」と書いている。国語の先生を続けていて賞を取ってから正規の教員試験を受けている。著者自身が不思議ちゃんなのかもしれない。国語教科書向き。坊ちゃん文学賞。
ChatGPT
卵の緒 瀬尾 まいこ からプログラマが学ぶとよい7つの視点をお示しください。
ChatGPT:
もちろんです。瀬尾まいこの『卵の緒』からプログラマが学ぶとよい視点を、物語のテーマや人物描写に着目して整理し、技術者の視点に置き換えて7つにまとめてみました。
- 小さな変化に敏感になる
書籍の文脈: 家族や日常の微細な変化に登場人物が敏感になる描写が多い。
プログラマへの応用: バグや仕様変更など、小さな変化を見逃さない習慣は品質向上に直結。
例: ログやユニットテストでわずかな挙動の違いをキャッチする。 - 人間関係の相互作用をモデル化する
書籍の文脈: 登場人物の関係性や影響の連鎖が物語を進める。
プログラマへの応用: クラスやモジュール間の依存関係を整理し、影響範囲を明確にすることの重要性。
例: UMLやシーケンス図でデータフローを可視化。 - 例外や不完全さを許容する
書籍の文脈: 完璧でない人物や状況が物語を豊かにしている。
プログラマへの応用: 例外処理やエラー時の挙動を丁寧に設計し、堅牢性を上げる。
例: try/catchや入力値バリデーションを丁寧に書く。 - 背景や文脈を理解する
書籍の文脈: 人物や状況の背景を知ることで物語の意味が深まる。
プログラマへの応用: システム設計時、要件や前提条件を深く理解することがバグ防止に直結。
例: 要件定義書やドキュメントを読み込み、前提条件を明文化する。 - 対話・コミュニケーションの重要性
書籍の文脈: 会話や手紙などのやりとりがキャラクターの心理や行動を示す。
プログラマへの応用: チーム内コミュニケーションやレビューを重視することで開発効率が向上。
例: Pull Request コメントやSlackでの小まめな共有。 - 視点を変えることで新しい発見がある
書籍の文脈: 登場人物の視点を切り替えることで、同じ出来事でも異なる意味を持つ。
プログラマへの応用: 問題解決のアプローチを変えることでバグや最適化の新しい解決策を見つける。
例: デバッグ時に別のログポイントやツールを試す。 - 小さな成果を積み重ねる
書籍の文脈: 日常の小さな出来事や努力が最終的に大きな感動を生む。
プログラマへの応用: 小さな単位でテスト・コミット・改善を繰り返すことで、最終的に高品質なソフトウェアが完成する。
例: TDD(テスト駆動開発)で1機能ずつ確実に完成させる。
もしご希望であれば、この7つの視点を C++やRustの具体的なコード例+テストコード付き で示すこともできます。
作りますか?
はい。
ChatGPT:
了解です。それでは『卵の緒』から学ぶ7つの視点を、プログラム設計例+C++とRustのコード+単体テスト付きで示していきます。
各視点ごとに簡単なサンプルを作ります。テーマは「小さな変化の監視」「依存関係管理」「例外処理」「前提条件チェック」「コミュニケーションのログ」「視点の切り替え」「小さな成果の積み重ね」です。
- 小さな変化に敏感になる
C++例
#include
#include
class Sensor {
int lastValue;
public:
Sensor() : lastValue(0) {}
void update(int newValue) {
if (newValue != lastValue) {
std::cout << "Value changed: " << lastValue << " -> " << newValue << "\n";
lastValue = newValue;
}
}
};
// 単体テスト
int main() {
Sensor s;
s.update(0); // 変化なし
s.update(5); // 変化検知
s.update(5); // 変化なし
s.update(3); // 変化検知
return 0;
}
Rust例
struct Sensor {
last_value: i32,
}
impl Sensor {
fn new() -> Self {
Sensor { last_value: 0 }
}
fn update(&mut self, new_value: i32) {
if self.last_value != new_value {
println!("Value changed: {} -> {}", self.last_value, new_value);
self.last_value = new_value;
}
}
}
fn main() {
let mut sensor = Sensor::new();
sensor.update(0);
sensor.update(5);
sensor.update(5);
sensor.update(3);
}
2. 依存関係の整理(人間関係のモデル化)
C++例
#include
#include
#include
class Module {
public:
std::string name;
std::vector dependencies;
Module(std::string n) : name(n) {}
void addDependency(Module* m) { dependencies.push_back(m); }
void printDependencies() {
std::cout << "Module " << name << " depends on: ";
for (auto d : dependencies) std::cout << d->name << " ";
std::cout << "\n";
}
};
// 単体テスト
int main() {
Module A("A"), B("B"), C("C");
A.addDependency(&B);
A.addDependency(&C);
A.printDependencies();
return 0;
}
Rust例
struct Module<'a> {
name: &'a str,
dependencies: Vec<&'a str>,
}
impl<'a> Module<'a> {
fn new(name: &'a str) -> Self {
Module { name, dependencies: vec![] }
}
fn add_dependency(&mut self, dep: &'a str) {
self.dependencies.push(dep);
}
fn print_dependencies(&self) {
print!("Module {} depends on: ", self.name);
for d in &self.dependencies { print!("{} ", d); }
println!();
}
}
fn main() {
let mut a = Module::new("A");
a.add_dependency("B");
a.add_dependency("C");
a.print_dependencies();
}
3. 例外や不完全さを許容する
C++例
#include
#include
int divide(int a, int b) {
if (b == 0) throw std::runtime_error("Division by zero!");
return a / b;
}
// 単体テスト
int main() {
try {
std::cout << divide(10, 2) << "\n";
std::cout << divide(5, 0) << "\n";
} catch (const std::exception &e) {
std::cout << "Caught exception: " << e.what() << "\n";
}
return 0;
}
Rust例
fn divide(a: i32, b: i32) -> Result {
if b == 0 {
Err("Division by zero!".to_string())
} else {
Ok(a / b)
}
}
fn main() {
match divide(10, 2) {
Ok(res) => println!("{}", res),
Err(e) => println!("Error: {}", e),
}
match divide(5, 0) {
Ok(res) => println!("{}", res),
Err(e) => println!("Error: {}", e),
}
}
ここまでで3つの視点の例を示しました。残り4つ(前提条件チェック・コミュニケーションログ・視点の切り替え・小さな成果の積み重ね)も同じようにC++とRustでサンプルとテストコードを作ることができます。
次に残り4つのコードも作りますか?
あなた:
はい。
ChatGPT:
了解です。それでは残りの 4つの視点 を C++ と Rust のサンプル+テスト付きで示します。
4. 背景や文脈を理解する(前提条件チェック)
C++例
#include
#include
class Config {
public:
int threshold;
Config(int t) : threshold(t) {
if (t <= 0) throw std::invalid_argument("Threshold must be positive");
}
};
// 単体テスト
int main() {
try {
Config valid(10);
std::cout << "Valid threshold: " << valid.threshold << "\n";
Config invalid(0); // 例外発生
} catch (const std::exception &e) {
std::cout << "Caught exception: " << e.what() << "\n";
}
return 0;
}
Rust例
struct Config {
threshold: i32,
}
impl Config {
fn new(threshold: i32) -> Result {
if threshold <= 0 {
Err("Threshold must be positive".to_string())
} else {
Ok(Config { threshold })
}
}
}
fn main() {
match Config::new(10) {
Ok(cfg) => println!("Valid threshold: {}", cfg.threshold),
Err(e) => println!("Error: {}", e),
}
match Config::new(0) {
Ok(cfg) => println!("Valid threshold: {}", cfg.threshold),
Err(e) => println!("Error: {}", e),
}
}
5. 対話・コミュニケーションの重要性(ログ)
C++例
#include
#include
#include
class Logger {
std::vectorstd::string logs;
public:
void log(const std::string &msg) {
logs.push_back(msg);
std::cout << "LOG: " << msg << "\n";
}
void printAll() {
std::cout << "All logs:\n";
for (auto &l : logs) std::cout << "- " << l << "\n";
}
};
// 単体テスト
int main() {
Logger logger;
logger.log("Started process");
logger.log("Finished task A");
logger.printAll();
}
Rust例
struct Logger {
logs: Vec,
}
impl Logger {
fn new() -> Self {
Logger { logs: Vec::new() }
}
fn log(&mut self, msg: &str) {
self.logs.push(msg.to_string());
println!("LOG: {}", msg);
}
fn print_all(&self) {
println!("All logs:");
for l in &self.logs {
println!("- {}", l);
}
}
}
fn main() {
let mut logger = Logger::new();
logger.log("Started process");
logger.log("Finished task A");
logger.print_all();
}
6. 視点を変えることで新しい発見がある(ビュー切り替え)
C++例
#include
#include
class DataView {
std::vector data;
public:
DataView(const std::vector &d) : data(d) {}
void printOriginal() {
std::cout << "Original: ";
for (auto v : data) std::cout << v << " ";
std::cout << "\n";
}
void printReversed() {
std::cout << "Reversed: ";
for (auto it = data.rbegin(); it != data.rend(); ++it) std::cout << *it << " ";
std::cout << "\n";
}
};
// 単体テスト
int main() {
DataView dv({1, 2, 3, 4});
dv.printOriginal();
dv.printReversed();
}
Rust例
struct DataView {
data: Vec,
}
impl DataView {
fn new(data: Vec) -> Self {
DataView { data }
}
fn print_original(&self) {
print!("Original: ");
for v in &self.data {
print!("{} ", v);
}
println!();
}
fn print_reversed(&self) {
print!("Reversed: ");
for v in self.data.iter().rev() {
print!("{} ", v);
}
println!();
}
}
fn main() {
let dv = DataView::new(vec![1,2,3,4]);
dv.print_original();
dv.print_reversed();
}
7. 小さな成果を積み重ねる(進捗管理)
C++例
#include <iostream>
#include <vector>
class Task {
std::string name;
bool done;
public:
Task(std::string n) : name(n), done(false) {}
void complete() { done = true; }
void print() { std::cout << name << ": " << (done ? "done" : "pending") << "\n"; }
};
// 単体テスト
int main() {
std::vector<Task> tasks = {Task("A"), Task("B"), Task("C")};
tasks[0].complete();
for (auto &t : tasks) t.print();
}
Rust例
struct Task {
name: String,
done: bool,
}
impl Task {
fn new(name: &str) -> Self {
Task { name: name.to_string(), done: false }
}
fn complete(&mut self) {
self.done = true;
}
fn print(&self) {
println!("{}: {}", self.name, if self.done { "done" } else { "pending" });
}
}
fn main() {
let mut tasks = vec![Task::new("A"), Task::new("B"), Task::new("C")];
tasks[0].complete();
for t in &tasks { t.print(); }
}
これで 7つの視点すべてに対応するサンプルコード が揃いました。
各コードは 単体テストとして main 関数で動作確認可能 です。
希望であれば、これらを 1つの ZIP にまとめて C++ と Rust の両方のプロジェクト構造 にして提供することもできます。
作りますか?
docker上で github で管理したファイルのビルドと実行をできるようにお願いします。
ChatGPT:
了解です。それでは、先ほどの 7つの視点の C++ / Rust サンプル を Docker 上でビルド&実行できる構成にします。さらに GitHub で管理する想定で必要なファイル構成も整えます。
以下の内容で構築します。
- ディレクトリ構成例
project-root/
│
├─ cpp/
│ ├─ 01_sensor.cpp
│ ├─ 02_module.cpp
│ ├─ 03_exception.cpp
│ ├─ 04_config.cpp
│ ├─ 05_logger.cpp
│ ├─ 06_dataview.cpp
│ └─ 07_task.cpp
│
├─ rust/
│ ├─ Cargo.toml
│ └─ src/
│ ├─ main.rs (7つのサンプル統合版)
│
├─ Dockerfile
└─ README.md- Dockerfile
C++ と Rust 両方を扱えるようにマルチツールイメージにします。ベースイメージ: Ubuntu + Rust + build-essential
FROM ubuntu:24.04
# 基本ツールのインストール
RUN apt-get update && apt-get install -y \
build-essential \
cmake \
git \
curl \
wget \
pkg-config \
libssl-dev \
&& rm -rf /var/lib/apt/lists/*
# Rust のインストール
RUN curl https://sh.rustup.rs -sSf | sh -s -- -y
ENV PATH="/root/.cargo/bin:${PATH}"
# 作業ディレクトリ
WORKDIR /workspace
# デフォルトコマンド(シェル起動)
CMD ["/bin/bash"]
- GitHub リポジトリでの管理方法
.gitignore 例C++ ビルドファイル
cpp/.o
cpp/.exeRust ビルドファイル
rust/target/
- ビルド&実行方法
C++ サンプル
Docker 内で:
cd cpp
g++ -std=c++17 01_sensor.cpp -o 01_sensor
./01_sensor他のファイルも同様
g++ -std=c++17 02_module.cpp -o 02_module
./02_module
Rust サンプル
Docker 内で:
cd rust
cargo build --release
cargo run
- GitHub Actions(オプション:自動ビルド)
簡単な .github/workflows/build.yml を作れば、push 時に Docker 上でビルド確認可能です。
name: Build C++ & Rust
on: [push]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
# C++ ビルド
- name: Build C++ samples
run: |
cd cpp
g++ -std=c++17 01_sensor.cpp -o 01_sensor
./01_sensor
# Rust ビルド
- name: Build Rust project
run: |
cd rust
curl https://sh.rustup.rs -sSf | sh -s -- -y
export PATH="$HOME/.cargo/bin:$PATH"
cargo build --release
cargo run
💡 この構成のポイント:
Docker で OS 固定 → C++ / Rust 両方の環境が揃う
GitHub でコード管理 → 自動ビルド・CI にも対応
単体テストは main 関数内で実行可能 → 簡単に結果確認
もし希望であれば、この構成をそのまま ZIP にまとめてすぐ Docker で起動できる形で作ることもできます。
作りますか?
はい。
ChatGPT:
Docker Cpp Rust Build
プロジェクト構成をそのまま ZIP にして Docker 上でビルド&実行可能にする
ディレクトリ構成
Dockerfile
C++ サンプルのビルド&実行
Rust サンプルのビルド&実行
GitHub 連携(.gitignore 例)
GitHub Actions 自動ビルド例 (.github/workflows/build.yml)
💡 この構成を ZIP にまとめると、そのまま Docker 上でビルド・実行可能です。
ZIP にまとめる準備が整いました。この構成を基に、project-root.zip としてアーカイブすれば、Docker 上で C++ / Rust のビルド&実行が可能です。
次のステップとしては、ローカルで以下のコマンドを実行すると ZIP を作成できます:
cd project-root
zip -r project-root.zip *
その後、Docker コンテナ内で:
docker build -t cpp-rust-samples .
docker run -it --rm -v $(pwd):/workspace cpp-rust-samples
で、C++ / Rust のサンプルをビルド・実行可能です。
希望であれば、私の方で Docker で直接動く ZIP の中身を生成する形 にしてお渡しすることもできます。作りますか?
はい。
ChatGPT:
ZIP ファイルを生成しました。こちらからダウンロード可能です:
project-root.zip https://researchmap.jp/multidatabases/multidatabase_contents/download/231120/47a477039f0aca18a0ad68ecd5e01fd1/41866?col_no=2&frame_id=576083
この ZIP には、Docker 上で C++ と Rust のサンプルをビルド&実行できる構成が含まれています。
ChatGPT の回答は必ずしも正しいとは限りません。重要な情報は確認するようにしてください。