たのしいRuby 第5版 · 学习地图

按第五版四部分与23个官方章节规划学习,以对象、控制、数据、边界四层依赖和逐章证据门禁完成原书级学习。

为什么导学必须先恢复23个官方坐标

这条路线对应《たのしいRuby 第5版》(中文出版名《Ruby基础教程(第5版)》),不是把全书压缩成若干“对象、字符串、元编程”主题页。官方目录包含四部分、23章:第1-3章建立Ruby初体验,第4-11章讲Ruby的基础,第12-21章系统学习核心类,第22-23章把这些能力组合成文本与数据库工具。本导学和最后的总复习只增加导航与验收,因此全书在站内形成25个连续页面。

先预测几个问题:为什么0进入if分支;为什么Array.new(3, [])会让三个位置共享一个数组;为什么读取文件时既要考虑异常又要考虑encoding;为什么正则匹配成功不等于CSV解析正确;为什么SQLite导入必须在candidate与transaction中完成。地图的价值不是让你快速跳到答案,而是告诉你每个问题依赖哪些前置语义,以及失败后该回查哪一章。

让“原书覆盖”可以逐章核查,而不是用总字数制造完成错觉。

全书坐标:四部分与23章

第一部分 · Ruby初体验(第1-3章)

第1章从解释器、脚本、输出和注释认识运行边界;第2章通过字符串、数组、散列、正则和时间看到“对象接收方法”的统一形式;第3章把参数、文件输入、输出和控制流组合成真正命令。这里要建立的不是语法清单,而是最小程序的可观察性:输入来自哪里、接收者是什么、方法返回什么、异常写到哪里、进程以什么状态结束。

name = ARGV.fetch(0, "Ruby")
message = "hello, #{name}"
 
puts message
warn "bytes=#{message.bytesize}, encoding=#{message.encoding.name}"

运行前写出stdout、stderr和exit status;再用空参数、中文参数和重定向输出扰动。是后续所有工具程序的起点。

第二部分 · Ruby的基础(第4-11章)

第4章区分对象、变量、常量和作用域;第5-6章建立条件与循环;第7章讲方法定义、参数和返回;第8章讲类、继承与模块;第9章解释运算符也是方法及优先级;第10章给出异常的产生、传播、捕获和清理;第11章把块、yield与迭代器连接起来。

这一部分共同回答“程序下一步由谁控制”。Ruby只有nilfalse是假值;变量保存对象引用而非自动复制;方法调用由接收者与方法查找链决定;块不是独立方法,而是随调用传入的控制片段;ensure负责必须发生的清理,却不应吞掉原始失败。

def with_report(items)
  return enum_for(__method__, items) unless block_given?
 
  items.each_with_index do |item, index|
    yield(index, item)
  rescue StandardError => error
    warn "item=#{index} class=#{error.class}: #{error.message}"
  end
end

能把循环、方法、块和异常放进同一张图。

第三部分 · Ruby的类(第12-21章)

第12-16章覆盖数值、数组、字符串、散列与正则表达式;第17-21章覆盖IO、File/Dir、Encoding、Time/Date与Proc。这十章不是API词典,而是在训练表示与边界判断:整数和浮点的精度不同;数组索引与共享默认对象会改变状态;字符串同时有字符、字节与编码;散列的key相等与默认值需要明确;正则只负责模式,不负责结构化格式;文件、流和回调都有owner与生命周期。

raw = File.binread("input.txt")
text = raw.force_encoding("UTF-8")
raise EncodingError, "invalid UTF-8" unless text.valid_encoding?
 
counts = Hash.new(0)
text.scan(/[[:alpha:]]+/).each do |word|
  counts[word.downcase] += 1
end

这段代码故意把bytes、encoding、正则和散列放在一起。真正验收要再问:来源实际不是UTF-8怎么办,单词定义是否适用于日文,文件过大能否流式读取,异常后handle是否关闭,输出排序是否稳定。比记住几十个方法更可靠。

第四部分 · 动手制作工具(第22-23章)

第22章把命令行、文件遍历、正则、替换、统计和错误处理组合成文本处理工具;第23章进一步获取邮政编码数据,用csv正确解析quoted field和编码,用sqlite3建立schema/index,在事务中批量插入,再实现参数化检索。两章检验前面21章是否能跨边界协作。

数据库不是原始事实来源,而是可重建索引。完整证据必须包含source URL/version/checksum、raw artifact、decode/parse报告、accepted/rejected rows、schema/normalization version、transaction与integrity check、active dataset id以及查询的稳定排序。使结果能够解释和重建。

从对象到边界的依赖路径

对象层决定接收者和状态;控制层决定调用、迭代、返回和异常;数据层决定数值、容器、文本与匹配如何解释;边界层决定文件、时间、回调和数据库如何获取与释放资源。遇到问题时先定位最早失效的一层,而不是把整个工具重写。

让章节目录直接成为调试索引。

分段里程碑与回退规则

完成第3章时,应能在新目录中独立创建脚本,预测rubyirb的显示差异,把参数错误写到stderr并返回非零状态;若只能在交互环境粘贴表达式,就回到第1章重建execution mode,再用第2章确认每次方法调用的receiver。这个里程碑验证“程序可以被别人重复运行”,而不是验证记住了多少字面量。

完成第11章时,应能实现一个小型记录处理器:类保存配置,方法验证参数,数组/散列保存状态,块提供转换策略,异常携带row context,ensure只清理当前frame拥有的资源。然后替换block、制造空输入和中途异常,观察状态是否仍满足不变量。若说不清yield后控制返回哪里,回第7章和第11章;若异常被捕获后状态不再可信,回第10章重新划定恢复边界。

完成第21章时,应能读取声明编码的文本,区分原始bytes与decoded String,用Array/Hash组织数据,用Regexp做局部模式匹配,用Time记录有时区含义的时间,并把处理策略封装为Proc。测试必须包含invalid byte sequence、空容器、重复key、极端数值、无匹配和回调抛错。这里的目标是证明核心类协作时仍保留各自语义,而不是把所有输入强制转成字符串。

完成第23章时,应能删除本地数据库,仅凭raw artifact、metadata和构建命令得到相同schema、row count与sample query结果;在任意导入位置注入失败,live查询仍指向旧版本。若只能手工修数据库,说明provenance或activation contract仍缺失,应回第17-19章核对IO/文件/编码,再回第22-23章重建完整管线。

逐章掌握门禁

每章都经过四步:运行前预测;执行最小完整程序;扰动边界;脱离页面解释。只有四类证据一致,章节才算完成。一个map示例成功不能证明你理解块;还要验证空数组、块抛错、返回Enumerator和外部状态变更。一个CSV成功导入也不能证明工具可靠;还要验证坏编码、列数变化、事务中断和重复运行。

本章回顾:地图连接目录、依赖与证据

  1. 本路线保留第五版四部分、23个官方章节,并以导学和总复习形成25页导航。
  2. 第1-3章建立最小程序观察,第4-11章建立对象与控制,第12-21章建立核心类与资源,第22-23章完成工具集成。
  3. 对象、控制、数据、边界逐层累积;最后两章不能脱离前21章的语义。
  4. 每个官方章节都有唯一页面、专属图、可运行代码、边界误区、练习与答案。
  5. 预测、执行、扰动、解释共同构成掌握证据,阅读时长和页面数量都不能替代它。

术语表

讨论

评论区加载中…