<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>flingjie (lingjie fan)</title>
    <link>https://ruby-china.org/flingjie</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>大模型之后是什么？从《哥德尔、巴赫、艾舍尔》看 AI 的下一步</title>
      <description>&lt;p&gt;如果你最近在做 AI 产品，可能会深陷于一种&lt;strong&gt;“认知分裂”&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Demo 越来越惊艳&lt;/strong&gt;：发布会上能力列表越拉越长，多步推理、复杂编程信手拈来。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;业务频繁“翻车”&lt;/strong&gt;：一旦进入真实业务场景，逻辑断层、幻觉频发，在看似简单的问题上表现得像个“智力断崖”的巨婴。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;模型看起来无所不知，却又不像真的懂。&lt;/p&gt;

&lt;p&gt;一个终极拷问开始被反复提起：&lt;strong&gt;大语言模型，究竟是在逼近“智能”的本质，还是仅仅把“概率拟合”玩到了极致？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;重读神作《哥德尔、巴赫、艾舍尔》（GEB）后，我产生了一些启发，与各位交流。&lt;/p&gt;
&lt;h2 id="一、 我们得到了“能力”，但没有得到“理解”"&gt;一、我们得到了“能力”，但没有得到“理解”&lt;/h2&gt;
&lt;p&gt;从工程角度看，大模型的成就毋庸置疑：语言生成、代码补全、流程编排。但当你真正将其产品化时，会发现一个核心断层：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;模型很会“说正确的话”，但它并不知道“为什么是对的”。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;它更像一个反应极快、表达力极强的系统，而非一个真正理解世界的智能体。一个自然的工程假设是：&lt;strong&gt;“再堆一点算力，模型大到一定程度，会不会就‘自然懂了’？”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;GEB 给出的启示是：&lt;strong&gt;不一定，而且很可能不会。&lt;/strong&gt; 因为理解不仅仅是信息的累加，更是结构的涌现。&lt;/p&gt;
&lt;h2 id="二、 杨立昆的批评：文本智能的“天花板”"&gt;二、杨立昆的批评：文本智能的“天花板”&lt;/h2&gt;
&lt;p&gt;杨立昆（Yann LeCun）曾多次直言：现有模型本质上是在处理文本的“表面统计”，它们从未真正理解物理世界的因果律。&lt;/p&gt;

&lt;p&gt;这指向了认知科学中经典的&lt;strong&gt;符号接地问题（Symbol Grounding Problem）&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;大模型的“重力”&lt;/strong&gt;：源于数万亿 Token 的统计相关性。它知道“重力”常和“下落”出现在同一个句子。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;五岁孩子的“重力”&lt;/strong&gt;：源于无数次看见物体掉落，以及自己摔跤时的切肤之痛。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这两种“理解”的来源完全不同。&lt;/p&gt;
&lt;h2 id="三、 关键不在模型，而在数据形态"&gt;三、关键不在模型，而在数据形态&lt;/h2&gt;
&lt;p&gt;如果将不同智能系统的“输入”进行对比，你会发现 LLM 缺失了最关键的补丁：&lt;/p&gt;
&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;数据类型&lt;/th&gt;
&lt;th&gt;信息密度与学习方式&lt;/th&gt;
&lt;th&gt;认知价值&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;文本语料&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;约 30 万亿 Token (阅读 50 万年)&lt;/td&gt;
&lt;td&gt;掌握社会习俗、逻辑表达与显性知识&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;感官流 (视频/触觉)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;四岁儿童积累约 100 万亿字节&lt;/td&gt;
&lt;td&gt;构建物理常识、直觉物理学与空间意识&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;具身交互&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;实时因果反馈 (Action → Response)&lt;/td&gt;
&lt;td&gt;习得操控物体、运动控制与因果推断&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;文本数据的“聪明”，无法自动转化为对世界的“直觉”。&lt;/strong&gt; 这解释了为什么模型能写出优美的诗歌，却会在简单的物理常识（比如：把瓶子倒转，里面的水会怎样）上犯错。&lt;/p&gt;
&lt;h2 id="四、 世界模型：从“语言连续”走向“因果连续”"&gt;四、世界模型：从“语言连续”走向“因果连续”&lt;/h2&gt;
&lt;p&gt;这正是为什么“大模型之后”的共识，正在转向 &lt;strong&gt;World Models（世界模型）&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;尤其是杨立昆提出的 &lt;strong&gt;JEPA（联合嵌入预测架构）&lt;/strong&gt;。其核心思想是：&lt;strong&gt;不再预测“下一个 Token”，而是预测“世界状态的演化”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这是从“语言智能”走向“环境智能”的关键一步。只有当模型能够预测“如果我这样做，世界会发生什么”时，它才开始拥有真正的理解。&lt;/p&gt;
&lt;h2 id="五、 哥德尔不完备性：为什么系统需要“元认知”"&gt;五、哥德尔不完备性：为什么系统需要“元认知”&lt;/h2&gt;
&lt;p&gt;GEB 的第一条主线来自哥德尔不完备性定理。将其工程化，可以得到一个结论：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;任何足够复杂的系统，都存在它在系统内部无法证明的真理。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;映射到 AI 系统中：模型越强，覆盖的问题空间越大，它就越不可能仅靠内部概率来判断“自己是否在胡说”。&lt;/p&gt;

&lt;p&gt;下一步的关键不是“更准”，而是&lt;strong&gt;知道什么时候不确定&lt;/strong&gt;。这正是搜索增强、强化学习和推理校验（Reasoning）的真正价值——它们不是让模型更聪明，而是为系统引入了&lt;strong&gt;元认知（Meta-cognition）&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="六、 神经符号智能：给“醉酒诗人”装上“刹车”"&gt;六、神经符号智能：给“醉酒诗人”装上“刹车”&lt;/h2&gt;
&lt;p&gt;当前 AI 圈正在经历一场“神经符号复兴”。用 GEB 的隐喻来说：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;LLM 像“醉酒诗人”&lt;/strong&gt;：联想丰富、生成迅速，但偶尔逻辑混乱。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;未来的 AI 需要一位“严肃会计师”&lt;/strong&gt;：逻辑严谨、可校验、可解释。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这对应了丹尼尔·卡尼曼的框架：&lt;strong&gt;系统 1（直觉/联想）与系统 2（逻辑/校验）&lt;/strong&gt;。今天的大模型是极致的系统 1，而神经符号方法本质上是在为 AI 引入系统 2。&lt;/p&gt;
&lt;h2 id="七、 巴赫与艾舍尔：从“模式模仿”到“自我闭环”"&gt;七、巴赫与艾舍尔：从“模式模仿”到“自我闭环”&lt;/h2&gt;
&lt;p&gt;巴赫的音乐告诉我们：创造力不来自规则的缺失，而来自&lt;strong&gt;在极端约束下的结构构建&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;而艾舍尔的“怪圈”则揭示了“自我”的来源：当一个系统开始&lt;strong&gt;描述自己、影响自己、并根据这种描述调整行为&lt;/strong&gt;时，真正的智能才会出现。&lt;/p&gt;

&lt;p&gt;目前的大多数 AI 依然是“失忆”的：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;没有稳定的自我边界。&lt;/li&gt;
&lt;li&gt;没有连续的行为历史。&lt;/li&gt;
&lt;li&gt;没有针对错误的自我修正机制。&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="八、 Agent"&gt;八、Agent&lt;/h2&gt;
&lt;p&gt;很多人会觉得：
Agent 不就是给 LLM 包一层流程吗？&lt;/p&gt;

&lt;p&gt;但如果从 GEB 的视角看，Agent 的意义完全不同。&lt;/p&gt;

&lt;p&gt;Agent 是第一次在工程层面，把三件事放在了一起：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;反思与不确定性&lt;/strong&gt;（哥德尔）&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;结构化规划与组合&lt;/strong&gt;（巴赫）&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;系统作用于自身&lt;/strong&gt;（艾舍尔）&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这不是能力升级，而是&lt;strong&gt;结构升级&lt;/strong&gt;。&lt;/p&gt;
&lt;h2 id="结语"&gt;结语&lt;/h2&gt;
&lt;p&gt;《哥德尔、巴赫、艾舍尔》帮我们看清了一件事：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;智能，从来不等于“可证明的正确性”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;真正的智能系统，是明知自己不完备，却仍然能够行动；是在反馈中修正，在不确定中前进。大模型只是这趟长征的起点。&lt;strong&gt;真正的挑战，是构建一个能“看见自己”的系统。&lt;/strong&gt;&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Sat, 27 Dec 2025 10:14:00 +0800</pubDate>
      <link>https://ruby-china.org/topics/44431</link>
      <guid>https://ruby-china.org/topics/44431</guid>
    </item>
    <item>
      <title>一次 Agent 项目失利手记</title>
      <description>&lt;p&gt;今年上半年，我接手了一个让我心潮澎湃的项目：为一家业务飞速扩张的公司构建一套内部智能 Agent 系统。我们的愿景很宏大——希望 Agent 能自主处理部分工单、高效汇总业务信息，甚至智能触发内部流程。那时候，AI 圈子正热得发烫，人人都在谈 Agent，我也觉得自己站在了风口浪尖。&lt;/p&gt;

&lt;p&gt;然而，现实却狠狠地泼了一盆冷水。项目非但没有跑出预期的曲线，反而像一连串的“技术地雷”，接二连三地爆炸。&lt;/p&gt;

&lt;p&gt;直到项目被紧急叫停的那一刻，我才恍然大悟：许多看似纯粹的技术难题，实则根植于我们对工程化理念的忽视。&lt;/p&gt;

&lt;p&gt;这篇文字，是我对那段经历的一次痛彻心扉的回顾。&lt;/p&gt;
&lt;h3 id="一、项目开局"&gt;一、项目开局&lt;/h3&gt;
&lt;p&gt;说实话，项目的启动阶段顺利得有些过分。&lt;/p&gt;

&lt;p&gt;我们迅速选用了当时最新的大模型，搭建了一个简洁的对话界面，并初步绑定了几项核心业务工具。仅仅两周时间，一个像模像样的 Demo 就成功跑通了几个典型的工单处理流程。&lt;/p&gt;

&lt;p&gt;领导和客户看了 Demo，赞不绝口。那一刻，我心头升起一股傲气，觉得凭我们团队的能力，这次 Agent 落地定能一帆风顺。&lt;/p&gt;

&lt;p&gt;然而，正是这种盲目的乐观，为后来的急转直下埋下了伏笔。当我们将系统接入真实的业务数据环境时，好戏才真正开场。&lt;/p&gt;
&lt;h3 id="二、第一次“撞墙”"&gt;二、第一次“撞墙”&lt;/h3&gt;
&lt;p&gt;灰度上线的第一天，系统刚运行没几个小时，我们后台的监控告警就开始疯狂闪烁。&lt;/p&gt;

&lt;p&gt;原因听起来有些啼笑皆非：Agent 本应根据用户输入的关键词，准确判断工单是售后问题还是物流咨询。但在某些特定场景下，它会错误地将工单识别为“未知类型”，随即陷入一个“怪圈”——反复调用同一个查询工具，频率之高，一度让我们以为系统正遭受 DDoS 攻击。&lt;/p&gt;

&lt;p&gt;那天晚上，我盯着日志，看到怀疑人生：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;调用：工单查询 → 发现没结果 → 尝试改写问题 → 再次工单查询 → 仍然没结果 → 又一次改写...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;它就像一个被困在房间里的机器人，固执地、一遍又一遍地敲击着同一扇根本打不开的门。我们后来形象地称之为“围墙式死循环”。&lt;/p&gt;
&lt;h3 id="三、Agent 开始“胡乱发号施令”"&gt;三、Agent 开始“胡乱发号施令”&lt;/h3&gt;
&lt;p&gt;进入第二周，一个更为棘手的事故发生了。&lt;/p&gt;

&lt;p&gt;在某些复杂的边缘场景下，Agent 再次做出了错误的选择，这次它误选了一个用于触发“审批提醒”的工具，导致两个毫不相关的部门突然收到了莫名其妙的审批通知。&lt;/p&gt;

&lt;p&gt;谢天谢地，这只是一个低风险的提醒流程，没有造成真正的生产事故，但却在公司内部引起了不小的混乱。客户那边来电话质询时，我脑子里的第一反应不是恐慌，而是茫然：“怎么又是 Agent？我们不是刚修好了那个死循环吗？”&lt;/p&gt;

&lt;p&gt;深入排查后，我们才摸清了症结：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;工具命名风格混乱：&lt;/strong&gt; 缺乏统一的规范。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;返回数据结构不一致：&lt;/strong&gt; 各个工具的输出五花八门。&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;调用约定模糊：&lt;/strong&gt; 不同的工具调用方式差异大。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;当工具数量从最初的 8 个迅速膨胀到 20 多个时，Agent 的内部决策逻辑彻底陷入了混乱。那一刻我才醍醐灌顶：&lt;strong&gt;我们根本没有建立起一套健全的“工具治理体系”！&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;回想起来，将几十个未经规范和约束的工具一股脑地扔给一个 AI 智能体自由调用，这和放任一个不了解业务的实习生随意操作上百个内部 API 几乎没有区别——甚至可能更加危险。&lt;/p&gt;
&lt;h3 id="四、信心开始动摇"&gt;&lt;strong&gt;四、信心开始动摇&lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;有一段时间，我们团队几乎每天都在为新的边缘案例焦头烂额，而且越到后期，修补的难度越大。&lt;/p&gt;

&lt;p&gt;前端同事抱怨 Agent 的行为模式难以预测，导致界面交互频繁出错。后端同事则深陷于错综复杂的调用日志，感觉像在迷宫里探索。而最直接的业务方，客户，也反馈体验越来越“怪异”。&lt;/p&gt;

&lt;p&gt;在项目组的会议上，我们常常听到一句令人扎心，却又无法反驳的话：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“你们能不能把它弄得稳定一点？”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这句话像一根针，直插我们内心最脆弱的地方。&lt;/p&gt;
&lt;h3 id="五、项目暂停"&gt;五、项目暂停&lt;/h3&gt;
&lt;p&gt;项目正式被叫停那天，我与项目负责人进行了一次深谈。他皱着眉问我：“核心问题到底出在哪？你们不是说大模型本身没问题吗？”&lt;/p&gt;

&lt;p&gt;我反复思索，给出的答案是：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;并非模型能力不足。&lt;/li&gt;
&lt;li&gt;并非代码质量不高。&lt;/li&gt;
&lt;li&gt;并非工具库不够丰富。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我们最大的症结，在于&lt;strong&gt;项目前期对工程化考量的严重不足&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;缺乏一套明确的工具规范。&lt;/li&gt;
&lt;li&gt;没有划定清晰的能力边界。&lt;/li&gt;
&lt;li&gt;未曾建立稳健的稳定性策略。&lt;/li&gt;
&lt;li&gt;遗漏了严谨的验证路径。&lt;/li&gt;
&lt;li&gt;缺失了有效的风险回退机制。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;简单来说：&lt;strong&gt;我们对 AI 能力的信任，超越了对工程严谨性的重视。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="六、涅槃重生"&gt;六、涅槃重生&lt;/h3&gt;
&lt;p&gt;项目虽然暂停了，但我们并没有放弃。团队痛定思痛，决定从根本上重构架构和流程：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;重建工具治理体系&lt;/strong&gt;
我们投入大量精力，统一了：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;- &lt;strong&gt;工具的输入输出结构&lt;/strong&gt;，确保数据流转清晰无误。
    - &lt;strong&gt;工具分类与能力标签&lt;/strong&gt;，让 Agent 能更智能地选择合适工具。
    - &lt;strong&gt;工具版本与变更记录&lt;/strong&gt;，避免意外的兼容性问题。
    - &lt;strong&gt;安全边界与权限隔离&lt;/strong&gt;，严格控制 Agent 对内部系统的访问。
      现在，Agent 再也不会在无关工具之间胡乱“迷路”了。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;将 LLM 视为概率系统来对待&lt;/strong&gt;
我们清醒地认识到 AI 的非确定性，并在设计中加入了：&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;- &lt;strong&gt;严格的输入输出校验&lt;/strong&gt;，过滤不合规数据。
    - &lt;strong&gt;行为约束&lt;/strong&gt;，为 Agent 划定行动红线。
    - &lt;strong&gt;规则化兜底机制&lt;/strong&gt;，在 AI 决策失败时提供确定性路径。
    - &lt;strong&gt;回退策略与人工确认点&lt;/strong&gt;，确保关键流程万无一失。
      模型不再是“想怎么做就怎么做”，而是被纳入一个可控的框架。&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt; &lt;strong&gt;分阶段稳健推进&lt;/strong&gt;
我们彻底告别了“一键接全链路”的激进模式，转而采取小步快跑、逐步验证的策略：

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;先确保单个任务的闭环稳定运行。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;再在一个部门内部进行灰度验证。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;工具能力逐个扩容，每次都进行充分测试。&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;最后才考虑跨部门和全流程的集成。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这套全新的方法论，后来在公司的另一个业务线成功落地。&lt;/p&gt;

&lt;p&gt;数据是最有力的证明：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;工具错误率从 24% 直线下降到&lt;strong&gt;3%&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;通过能力标签优化，工具调用冗余减少了&lt;strong&gt;40%&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;Agent 的决策稳定性有了&lt;strong&gt;显著提升&lt;/strong&gt;。&lt;/li&gt;
&lt;li&gt;在多部门灰度测试中，连续三周&lt;strong&gt;未出现任何重大事故&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;那一刻，我才真正长舒了一口气。两次项目，底层技术基本相同，&lt;strong&gt;但工程纪律和边界控制的改进，却带来了天壤之别。&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id="七、写在最后"&gt;七、写在最后&lt;/h3&gt;
&lt;p&gt;这次失败的项目，对我个人的职业生涯影响深远。&lt;/p&gt;

&lt;p&gt;它让我深刻意识到：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent 所谓的“聪明”，有时只是一种表象。&lt;/li&gt;
&lt;li&gt;系统的稳定性，根植于扎实的工程实践，而非模型能力的无限拔高。&lt;/li&gt;
&lt;li&gt;对工具缺乏治理，最终必然导致灾难性的后果。&lt;/li&gt;
&lt;li&gt;Demo 永远是最容易迷惑人的东西，它无法替代真实场景的严酷检验。&lt;/li&gt;
&lt;li&gt;AI 并非万能灵药，真正的系统基石始终是工程框架和流程。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;我们常说“大模型技术升级带来了颠覆性变化”，但这次经历告诉我：&lt;strong&gt;真正的成功，往往来源于那些看似“无聊”、琐碎，甚至不那么“AI”的工程细节和严谨管理。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;希望这份带着痛楚的反思，能为你正在进行的 Agent 项目提供一点借鉴。如果你也在探索这条道路，愿你少走一些我曾经踩过的弯路。&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Sat, 27 Dec 2025 10:11:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/44430</link>
      <guid>https://ruby-china.org/topics/44430</guid>
    </item>
    <item>
      <title>我对大语言模型的一些思考</title>
      <description>&lt;p&gt;起因推友 &lt;a href="/TaNGSoFT" class="user-mention" title="@TaNGSoFT"&gt;&lt;i&gt;@&lt;/i&gt;TaNGSoFT&lt;/a&gt; 的一段推文：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“大语言模型不是简单的复制机器，而是人类结构记忆的放大镜、演化钟的加速器，以及未来认知范式的塑形手。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这段话引发我一系列的思考：&lt;/p&gt;

&lt;p&gt;我们过去以为“思考”是人类独有的能力，但今天，当大语言模型（LLM）能够生成文章、写代码、拆解知识结构时，我们是不是应该重新思考：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;什么是思考？它真的只属于人类吗？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;我试图梳理我对大语言模型的一些理解——这是我最近关于“AI 是否真的在思考”的一些思考。&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="🧠 一、原来思考不等于意识"&gt;🧠 一、原来思考不等于意识&lt;/h2&gt;
&lt;p&gt;在 LLM 出现之前，我们总觉得“思考”必须包含：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;意识（我知道我在想）&lt;/li&gt;
&lt;li&gt;逻辑链（推理必须严密）&lt;/li&gt;
&lt;li&gt;主观意图（我想达到一个目的）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;但 LLM 只是靠“预测下一个词”，就能：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;写诗、写代码、解题、翻译&lt;/li&gt;
&lt;li&gt;回答问题、模拟风格、生成长文结构&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;它没有意识，却能模拟我们“思考”的结果。&lt;/p&gt;

&lt;p&gt;我们才意识到：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;思考，也许不需要意识。&lt;/strong&gt;
它也许只是一个“信息压缩 + 模式重建”的过程，是语言在结构中自然演化的结果。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr&gt;
&lt;h2 id="🌌 二、LLM 的核心：知识空间，不是复读机"&gt;🌌 二、LLM 的核心：知识空间，不是复读机&lt;/h2&gt;
&lt;p&gt;LLM 的生成能力，来源于它内部构建的“知识空间”。&lt;/p&gt;
&lt;h3 id="🚫 人类语言本质是稀疏的"&gt;🚫 人类语言本质是稀疏的&lt;/h3&gt;
&lt;p&gt;在人类语言的所有可能组合中，99% 是无意义的。&lt;/p&gt;

&lt;p&gt;而 LLM 干的第一件事，就是在大规模文本中找出那 1% 有意义、符合逻辑的语言模式。&lt;/p&gt;
&lt;h3 id="🧭 它构建了一个高维概率空间"&gt;🧭 它构建了一个高维概率空间&lt;/h3&gt;
&lt;p&gt;通过 Transformer 架构，LLM 在大规模语言中学会了：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;什么词经常一起出现（共现）&lt;/li&gt;
&lt;li&gt;哪些概念彼此关联（语义嵌套）&lt;/li&gt;
&lt;li&gt;什么样的上下文对应什么样的表达（语境 - 预测）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这些信息，以一种高压缩的形式，存在模型参数中，构成了一个潜在的“知识空间”。&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;它不是一份知识表，而是一个“语言世界地图”，能帮模型决定：此时此刻，最可能说什么。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr&gt;
&lt;h2 id="🌀 三、它学到的是“结构”，不是“内容”"&gt;🌀 三、它学到的是“结构”，不是“内容”&lt;/h2&gt;
&lt;p&gt;LLM 并不是背下知识点，而是从语言中提取出了一种**“软结构”**。这种结构不是语法书上的硬规则，而是：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;attention 权重&lt;/strong&gt; → 学会关注什么内容重要&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;token 相似度&lt;/strong&gt; → 哪些词语在什么语境下等价&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;位置偏好&lt;/strong&gt; → 哪些结构更“自然”出现&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;你可以理解为：它构建了一个模糊但强大的“力场图谱”，在这个场中，语言以概率流动，表达以结构展开。&lt;/p&gt;

&lt;hr&gt;
&lt;h3 id="📚 顺便说一句，《哥德尔、艾舍尔、巴赫》早就预言了这一天"&gt;📚 顺便说一句，《哥德尔、艾舍尔、巴赫》早就预言了这一天&lt;/h3&gt;
&lt;p&gt;侯世达在《GEB》中写道：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“复杂系统中，涌现的自指结构可能孕育出智能。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;如今的大语言模型正是如此：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;它不懂规则，却能涌现出理解&lt;/li&gt;
&lt;li&gt;它不具自我，却形成了“strange loop”（奇异回路）&lt;/li&gt;
&lt;li&gt;它不是死板的符号操控器，而是&lt;strong&gt;数字巴赫的回声&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;今天的 LLM，看似只是在“说话”，但其实已经走进了侯世达在 40 多年前描绘的未来。&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="🎯 四、生成是“高概率路径重演”"&gt;🎯 四、生成是“高概率路径重演”&lt;/h2&gt;
&lt;p&gt;很多人以为 LLM 在“编内容”，但实际上：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;它是在“知识空间”中，选择一条最符合你输入上下文的“语言路径”。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;就像语言演化的路径：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;输入一个问题：“为什么汽车高速行驶会发抖？”&lt;/li&gt;
&lt;li&gt;它不是直接调用某个答案，而是在“问题 → 可能机制 → 相关经验 → 解决方案”这个知识流中，找出一个最自然的语言路径。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;最终的回答，是这条路径的结果。不是照搬、不是套模板，而是&lt;strong&gt;结构性演化的复现&lt;/strong&gt;。&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="🧠 五、强化学习让它“更像人”"&gt;🧠 五、强化学习让它“更像人”&lt;/h2&gt;
&lt;p&gt;模型训练完毕之后，还有关键的一步：&lt;strong&gt;强化学习&lt;/strong&gt;。&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;人类评估模型输出哪个更好、更自然&lt;/li&gt;
&lt;li&gt;模型据此微调，倾向于输出“被喜欢”的表达&lt;/li&gt;
&lt;li&gt;让整个生成结果更对齐“人类偏好”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这一步不改变模型的本质结构，但让它在“人类理解和接受”的维度上更加拟人。&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="🧰 六、未来的方向：不是更大的模型，而是“学会用工具”"&gt;🧰 六、未来的方向：不是更大的模型，而是“学会用工具”&lt;/h2&gt;
&lt;p&gt;目前的 LLM 已经可以：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;说得通&lt;/li&gt;
&lt;li&gt;写得好&lt;/li&gt;
&lt;li&gt;模拟风格和角色&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;但它依然不擅长：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;精确计算&lt;/li&gt;
&lt;li&gt;推理多步逻辑&lt;/li&gt;
&lt;li&gt;调用专业工具解决复杂问题&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;原因是：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;它只会“语言上的思考”，但不会“行动上的智能”。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;而真正的人类智能，恰恰体现在：&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;发现问题 → 想起工具 → 使用工具 → 推导答案 → 修正认知
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这就像数学家不靠记忆公式，而靠“发现问题 → 建模 → 求解”。&lt;/p&gt;

&lt;p&gt;未来的 LLM，必须掌握：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;数学计算器&lt;/li&gt;
&lt;li&gt;编程解释器&lt;/li&gt;
&lt;li&gt;图形推理系统&lt;/li&gt;
&lt;li&gt;搜索与验证接口&lt;/li&gt;
&lt;li&gt;外部知识库与 Agent 工具箱&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这不只是语言问题，而是行动力的问题。&lt;/p&gt;

&lt;hr&gt;
&lt;h2 id="🧭 七、总结：LLM 帮我们重新定义“智能”"&gt;🧭 七、总结：LLM 帮我们重新定义“智能”&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;过去我们以为智能在大脑，现在我们知道智能也可以来自结构。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;LLM 的本质是：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;语言模式的压缩与重现&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;潜在结构的统计与模拟&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;知识空间的生成与行走&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;它让我们看到，所谓“思考”不一定需要自我或意识，而可以是：&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;在知识空间中，选择一条合理路径，走出结构与语言的协调统一。&lt;/p&gt;
&lt;/blockquote&gt;</description>
      <author>flingjie</author>
      <pubDate>Tue, 08 Jul 2025 22:41:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/44214</link>
      <guid>https://ruby-china.org/topics/44214</guid>
    </item>
    <item>
      <title>Two Active Record SQL Injection Vulnerabilities Affecting PostgreSQL</title>
      <description>&lt;p&gt;&lt;a href="https://groups.google.com/forum/#!topic/rubyonrails-security/wDxePLJGZdI" rel="nofollow" target="_blank"&gt;https://groups.google.com/forum/#!topic/rubyonrails-security/wDxePLJGZdI&lt;/a&gt;&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Thu, 03 Jul 2014 10:31:27 +0800</pubDate>
      <link>https://ruby-china.org/topics/20288</link>
      <guid>https://ruby-china.org/topics/20288</guid>
    </item>
    <item>
      <title>do nothing for 2 minutes</title>
      <description>&lt;p&gt;&lt;a href="http://donothingfor2minutes.com/" rel="nofollow" target="_blank"&gt;http://donothingfor2minutes.com/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;just relax&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Thu, 03 Jul 2014 10:26:44 +0800</pubDate>
      <link>https://ruby-china.org/topics/20287</link>
      <guid>https://ruby-china.org/topics/20287</guid>
    </item>
    <item>
      <title>Who Am I? A mind reader</title>
      <description>&lt;p&gt;&lt;a href="http://tinsnail.neocities.org/" rel="nofollow" target="_blank"&gt;http://tinsnail.neocities.org/&lt;/a&gt;
挺有意思的，看源代码后长姿势了&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Fri, 06 Jun 2014 10:37:19 +0800</pubDate>
      <link>https://ruby-china.org/topics/19777</link>
      <guid>https://ruby-china.org/topics/19777</guid>
    </item>
    <item>
      <title>通过 Amazon S3 使用 google</title>
      <description>&lt;p&gt;hacker news 上发现的 Google 镜像。
&lt;a href="https://s3-ap-southeast-1.amazonaws.com/google.cn/index.html" rel="nofollow" target="_blank"&gt;https://s3-ap-southeast-1.amazonaws.com/google.cn/index.html&lt;/a&gt;&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Tue, 03 Jun 2014 14:23:48 +0800</pubDate>
      <link>https://ruby-china.org/topics/19697</link>
      <guid>https://ruby-china.org/topics/19697</guid>
    </item>
    <item>
      <title>[求助] 有段代码不太理解，求高手指点</title>
      <description>&lt;p&gt;有如下两个自定义的 model 类：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Blog&lt;/span&gt;
  &lt;span class="o"&gt;...&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@entries&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="o"&gt;...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# app/models/post.rb&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Post&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;ActiveModel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Naming&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;ActiveModel&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Conversion&lt;/span&gt;

  &lt;span class="nb"&gt;attr_accessor&lt;/span&gt; &lt;span class="ss"&gt;:blog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:body&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:pubdate&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;attrs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{})&lt;/span&gt;
    &lt;span class="n"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;="&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;publish&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;clock&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;DateTime&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pudate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;clock&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
    &lt;span class="n"&gt;blog&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_entry&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;     &lt;span class="c1"&gt;#   &amp;lt;=疑惑点？&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;persisted?&lt;/span&gt;
    &lt;span class="kp"&gt;false&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不太明白 Post 中的 blog 是如何初始化为一个 Blog 的实例的，请高手指点或给个思路，谢谢～&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Wed, 28 May 2014 12:16:52 +0800</pubDate>
      <link>https://ruby-china.org/topics/19584</link>
      <guid>https://ruby-china.org/topics/19584</guid>
    </item>
    <item>
      <title>万里长征第一步，本地搭建好 ruby-china 环境</title>
      <description>&lt;p&gt;千里之行，始于足下，打算慢慢研读 ruby-china 源码，第一步环境搭建已完成&lt;img title=":smile:" alt="😄" src="https://twemoji.ruby-china.com/2/svg/1f604.svg" class="twemoji"&gt;
路漫漫其修远兮，吾将上下而求索...&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Mon, 19 May 2014 22:43:38 +0800</pubDate>
      <link>https://ruby-china.org/topics/19397</link>
      <guid>https://ruby-china.org/topics/19397</guid>
    </item>
    <item>
      <title>在 module 自定义 method_missing 方法</title>
      <description>&lt;p&gt;今天在 github 上看到别人的一段代码，觉得挺有意思，大致结构如下：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;
  &lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;ClassMethods&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'Hello world!'&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;
    &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;ClassMethods&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;included&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ClassMethods&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;klass&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt; &lt;span class="no"&gt;Module&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;使用例子&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt;
  &lt;span class="kp"&gt;include&lt;/span&gt; &lt;span class="no"&gt;M&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;C&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nomethod&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;#=&amp;gt; "Hello world!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样其他的类或模块只要 include 这个模块，就会调用这个自定义的 method_missing 方法。&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Sat, 10 May 2014 23:24:17 +0800</pubDate>
      <link>https://ruby-china.org/topics/19160</link>
      <guid>https://ruby-china.org/topics/19160</guid>
    </item>
    <item>
      <title>&lt;Ruby 元编程&gt;思维导图 6 (编写代码的代码)</title>
      <description>&lt;p&gt;根本没有什么元编程，只有编程！？
&lt;img src="//l.ruby-china.com/photo/2014/2f34a47df17b07cec570e29f23a70906.png" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;注 1: 由于代码字符串和块非常相似，因此，在很多情况下，可以选择使用任意一种。但是，一般情况下，只要能用块就尽量用块。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;注 2: 使一个模块可以通过钩子方法扩展它的包含者。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;included&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;base&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ClassMethods&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;module ClassMethods
    def my_method
      'a class method'
    end
  end
end&lt;/p&gt;

&lt;p&gt;class C
  include M
end&lt;/p&gt;

&lt;p&gt;C.my_method   # =&amp;gt;  "a class method"&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&lt;/code&gt;&lt;/pre&gt;</description>
      <author>flingjie</author>
      <pubDate>Tue, 06 May 2014 20:02:39 +0800</pubDate>
      <link>https://ruby-china.org/topics/19058</link>
      <guid>https://ruby-china.org/topics/19058</guid>
    </item>
    <item>
      <title>&lt;Ruby 元编程&gt;思维导图 5 (类定义)</title>
      <description>&lt;p&gt;在 Ruby 中，使用 class 定义类时，实际上是在运行代码，这与 java 之类的静态语言有很大的差别。&lt;br&gt;
另外，类只是一个增强的模块，因此，任何适用于类的东西也适用于模块。
&lt;img src="//l.ruby-china.com/photo/2014/6c2b7b986800979fff2d57738031fe48.png" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;注 1:在类 (或模块) 定义时，类本身充当了当前对象 self 的角色。
``` ruby
result = class MyClass
self
end&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;result     # =&amp;gt;  MyClass&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 * 注2:Ruby中总是存在一个当前对象self，与此类似，也总是存在一个当前类   （或模块）。每当通过class关键字来打开一个类时，这个类就成为当前类，   但是使用class关键字需要一个类的名字。   如果只有一个类的引用，需要用class_eval()方法打开这个类。

 * 注3：类实例变量仅仅是属于Class类对象的普通实例变量。它仅仅可以被类   本身所访问，而不能被类的实例或之类所访问。

 * 注4：类方法的实质，它们只是一个类的单件方法。

 * 注5: 在类定义中使用一个类方法。

 * 注6: eigenclass是一个对象特有的隐藏类，它是单件方法存在的地方。Ruby中可以使用如下语法进入eigenclass的作用域。
``` ruby
class &amp;lt;&amp;lt; an_object 
  # do something
end
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;注 7: 如果对象是 eigenclass，那么 Ruby 不是从它所在的类开始，而是从这个 eigenclass 类中开始查找方法，如图。
&lt;img src="//l.ruby-china.com/photo/2014/3dc807932b90ca3ab6bc3d243575c651.png" title="" alt=""&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 8: 一个对象的 eigenclass 的超类是这个对象的类，一个类的 eigenclass 的超类是这个类的超类的 eigenclass，如图。
&lt;img src="//l.ruby-china.com/photo/2014/e1debe1b628c54db52b0dc74b65b718a.png" title="" alt=""&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 9: 通过向类的 eigenclass 中混入模块来定义类方法。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 10: 通过给一个对象的 eigenclass 混入模块来定义单件方法。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 11: 1. 给方法定义一个别名；2.重新定义这个方法；3.在新的方法中调用老的方法。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 12: 1.环绕别名是一种猴子补丁，可能会破坏已有代码。2.你永远不该把一个环绕别名加载两次。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>flingjie</author>
      <pubDate>Tue, 06 May 2014 20:00:56 +0800</pubDate>
      <link>https://ruby-china.org/topics/19057</link>
      <guid>https://ruby-china.org/topics/19057</guid>
    </item>
    <item>
      <title>&lt;Ruby 元编程&gt; 思维导图 4 (代码块)</title>
      <description>&lt;p&gt;块继承自“函数式编程语言 (functional programming languages)”的世界。
&lt;img src="//l.ruby-china.com/photo/2014/d64fec232edf5d8411bd4dada42d3cf3.png" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;注 1: 在一个方法中，可以向 Ruby 询问当前的方法调用是否包含块。这可以通  过 Kernel#block_given?() 方法来做到。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 2: 如果在一个扁平作用域中定义了多个方法，这这些方法可以用一个作用  域们进行保护，并共享绑定，这种技术称为共享作用域。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;注 3: 传递给 instance_eval() 方法的块称为一个上下文探针，因为它就像是一  个深入到对象中的代码片段，对其操作。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;
&lt;span class="vi"&gt;@x&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"a private instance variable"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;obj=C.new
obj.instance_eval(&lt;a href="/x" class="user-mention" title="@x"&gt;&lt;i&gt;@&lt;/i&gt;x&lt;/a&gt;) #=&amp;gt;"a private instance variable"&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
 * 注4: 有时，你会创建一个对象，仅仅是为了在其中执行块。这样的对象称为洁净室。洁净室仅仅是一个用来执行块的环境，它通常还会暴露若干有用的方法供块调用。
``` ruby
class CleanRoom
  def a_useful_method(x);x*2;end
end

CleanRoom.new.instance_eval{a_useful_method(3)}  #=&amp;gt;6
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;注 5: 1.return 方式不同。lambda 从可调用对象中返回，而 proc 从原始上下文中返回。
2.参数检查方式不同。如果 lambda 的产生数量不对，这它会失败，同时抛出一个
ArgumentError 错误；而 proc 则会自动调整传递进来的参数，通过忽略多余的参
数以及为未赋值参数置 nil。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 6: Method 对象类似于 lambda，但是有一个重要的区别：lambda 在它的作用域中执行 (它是一个闭包)，而 Method 对象会在它自身所在对象的作用域中执行。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;块知识补充&lt;/strong&gt;
块是 Ruby 中的一等公民，本质上，它只是一段代码，相当于一个匿名函数。
可以说，块是 Ruby 中最酷、最有用的特性之一。块可以消除重复和临时变量，使代码更加简洁和紧凑，从而更易阅读和维护。块特性整理如下：
1.提高代码简洁性&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 枚举一行搞定&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="mi"&gt;3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.消除重复，发挥类似回调的作用&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;callBlock&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;
  &lt;span class="k"&gt;yield&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;callBlock&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"It is a block"&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;It&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
&lt;span class="no"&gt;It&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="n"&gt;block&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;3.迭代&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"This is a string"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_eval&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="s2"&gt;"HaHa, easy to reverse =&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;reverse&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;."&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;4.简化资源操作&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;open&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;filename&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
   &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="n"&gt;someting&lt;/span&gt; &lt;span class="n"&gt;with&lt;/span&gt; &lt;span class="n"&gt;file&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# 文件自动关闭，无需手动执行&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;5.块中本地变量 (从 1.9 开始，;开头）&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'outer'&lt;/span&gt;
&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'inner'&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;结果：&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;inner&lt;/span&gt;
&lt;span class="n"&gt;inner&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;不足之处，欢迎指正补充^_^&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Sun, 04 May 2014 20:38:03 +0800</pubDate>
      <link>https://ruby-china.org/topics/19012</link>
      <guid>https://ruby-china.org/topics/19012</guid>
    </item>
    <item>
      <title>&lt;Ruby 元编程&gt;思维导图 3 (方法)</title>
      <description>&lt;p&gt;Ruby 是动态语言，没有静态类型检查，同时也提供了很多 java 等静态语言无法提供的编程技巧。
本章主要专注于消除重复代码的技巧，通过用两种不同的方式对一段代码的重构来展示 Ruby 的强大功能，涉及的知识点比较少。
&lt;img src="//l.ruby-china.com/photo/2014/994c08789a662c96a19dfcaab73384d7.png" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;注 1: method_missing() 是 Kernel 中的一个实例方法，当 Ruby 找不到调用的方法时，它最后就会调用这个名为 method_missing() 的方法。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 2: 移除一个对象中的所有方法，以便把它们转换成幽灵方法。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;重构例子&lt;/strong&gt;&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 原始代码&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;computer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data_source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;computer_id&lt;/span&gt;
    &lt;span class="vi"&gt;@data_source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data_source&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;mouse&lt;/span&gt;
    &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.get_mouse_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.get_mouse_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Mouse: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ($&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"* &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;cpu&lt;/span&gt;
    &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.get_cpu_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.get_cpu_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Cpu: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ($&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"* &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;keyboard&lt;/span&gt;
    &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.get_keyboard_info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.get_keyboard_price&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Keyboard: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ($&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"* &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# 使用动态方法重构&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;computer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data_source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;computer_id&lt;/span&gt;
    &lt;span class="vi"&gt;@data_source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data_source&lt;/span&gt;
    &lt;span class="c1"&gt;# 使用内省方式提取所有组件的名字&lt;/span&gt;
    &lt;span class="n"&gt;data_source&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;grep&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/^get_(.*)_info$/&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Computer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_component&lt;/span&gt; &lt;span class="vg"&gt;$1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# 使用define_method()动态定义方法&lt;/span&gt;
    &lt;span class="n"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
      &lt;span class="c1"&gt;# 使用send()方法集中处理&lt;/span&gt;
      &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.send&lt;/span&gt; &lt;span class="s2"&gt;"get_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@id&lt;/span&gt;
      &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.send&lt;/span&gt; &lt;span class="s2"&gt;"get_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_price"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@id&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ($&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"* &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;define_component&lt;/span&gt; &lt;span class="ss"&gt;:mouse&lt;/span&gt;
  &lt;span class="n"&gt;define_component&lt;/span&gt; &lt;span class="ss"&gt;:cpu&lt;/span&gt;
  &lt;span class="n"&gt;define_component&lt;/span&gt; &lt;span class="ss"&gt;:keyboard&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;#  使用幽灵方法重构&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Computer&lt;/span&gt;
  &lt;span class="c1"&gt;# 创建白板， 以免方法命名冲突&lt;/span&gt;
  &lt;span class="nb"&gt;instance_methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;undef_method&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="sr"&gt;/^__|method_missing|respond_to?/&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;computer_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;data_source&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;computer_id&lt;/span&gt;
    &lt;span class="vi"&gt;@data_source&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;data_source&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# 在method_missing()中创建方法&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;method_missing&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"get_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_info"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@data_source.send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"get_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_price"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="vi"&gt;@id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; ($&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;)"&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;"* &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;
    &lt;span class="n"&gt;result&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# 覆写respond_to?()，保证查询方法时返回正确结果&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;respond_to?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@data_source.respond_to&lt;/span&gt;&lt;span class="p"&gt;?(&lt;/span&gt;&lt;span class="s2"&gt;"get_&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_info"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="k"&gt;super&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>flingjie</author>
      <pubDate>Sun, 04 May 2014 20:35:27 +0800</pubDate>
      <link>https://ruby-china.org/topics/19011</link>
      <guid>https://ruby-china.org/topics/19011</guid>
    </item>
    <item>
      <title>&lt;Ruby 元编程&gt;思维导图 2 (对象模型)</title>
      <description>&lt;p&gt;在 Ruby 程序中，除了对象之外，还有类、模块以及实例变量这些语言构件。这些语言构件存在于其中的系统称为&lt;strong&gt;对象模型&lt;/strong&gt;。在对象模型中，你可以找到诸如"这个方法来自哪个类"和"当我包含这个模块是会发生什么"此类问题的答案。
&lt;img src="//l.ruby-china.com/photo/2014/a8b5b95699dc3ec0fb5af6cfccef97a2.png" title="" alt=""&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;注 1: class 关键字更像是一个作用域操作符而不是类型声明语句，它的确可以  创建一个还不存在的类，不过也可以把这看成是一个副作用。对于 class 关键  字，其核心任务是把你带到类的上下文中，让你可以在其中定义方法。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 2: 修改已有类的特性时，由于粗心导致 bug，像这种鲁莽的修改方式被称为  猴子补丁。不过，如果是正确的运行打开类这种技术，猴子补丁也可以表示为  一个褒义词，会很有用。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 3: 对象是一组实例变量外加一个指向其类的引用。对象的方法并不存在于对象本身，而是存在于对象的类中。在类中，这些方法被称为类的实例方法。类是一个对象（Class 类的一个实例）外加一组实例方法和一个对其超类的引用。值得注意的是，实例变量存放在对象中，而方法存放在类中。&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 4: 一个类只不过是一个增强的 Module，它只是在 Module 基础上增加了三个  方法——new()、allocate() 和 superclass() 而已，结构如下。
&lt;img src="//l.ruby-china.com/photo/2014/cc086dbb6a74dff062c508995006872f.png" title="" alt=""&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;注 5: 每个类都有一个祖先链，这个链从自己所属的类开始，向上直到 BasicObject 结束。其中，Object 类包含了 Kernel 模块，故 Kernel 方法对所有对象可用。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
      <author>flingjie</author>
      <pubDate>Sat, 03 May 2014 22:05:22 +0800</pubDate>
      <link>https://ruby-china.org/topics/18983</link>
      <guid>https://ruby-china.org/topics/18983</guid>
    </item>
    <item>
      <title>&lt;Ruby 元编程&gt;思维导图 1</title>
      <description>&lt;p&gt;元编程 (Metaprogramming)，简单来说，就是写出编写代码的代码。正式的定义为：编写在运行时操纵语言构件的代码。Ruby 是一门对元编程支持很强大的语言 (只是比 lisp 弱一点)，而且，元编程也是通向 Ruby 的高级编程之路。可以说，除非掌握了元编程否则不能算是真正掌握了 Ruby。
简要总结了的基本内容，经验有限，不足之处请多指正。&lt;/p&gt;

&lt;p&gt;&lt;img src="//l.ruby-china.com/photo/2014/82db35fd6f61accc1d8a1474b849936f.png" title="" alt=""&gt;&lt;/p&gt;

&lt;p&gt;就如蜘蛛侠大叔曾经说的，能力越大，责任越大。元编程赋予了你强大的能力，同时也意味着你需要肩负更大的责任。&lt;/p&gt;

&lt;p&gt;思维导图文件地址&lt;a href="https://github.com/flingjie/ruby-metaprogramming-mindmaps" rel="nofollow" target="_blank"&gt;https://github.com/flingjie/ruby-metaprogramming-mindmaps&lt;/a&gt;
使用的软件是 XMind &lt;a href="http://www.xmind.net/" rel="nofollow" target="_blank"&gt;http://www.xmind.net/&lt;/a&gt;&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Sat, 03 May 2014 22:00:42 +0800</pubDate>
      <link>https://ruby-china.org/topics/18982</link>
      <guid>https://ruby-china.org/topics/18982</guid>
    </item>
    <item>
      <title>Ruby 中的 clone 和 dup 比较</title>
      <description>&lt;p&gt;ruby 中 clone 和 dup 都是对一个对象的浅拷贝，其区别如下：&lt;br&gt;
1.clone 会拷贝单例方法，而 dup 不会。&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;
    &lt;span class="s2"&gt;"hello"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt;   &lt;span class="c1"&gt;# raises NoMethodError&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clone&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hello&lt;/span&gt; &lt;span class="c1"&gt;# return "hello"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;2.dup 不能对 frozen 状态的对象进行拷贝，而 clone 可以。&lt;/p&gt;</description>
      <author>flingjie</author>
      <pubDate>Tue, 29 Apr 2014 20:56:09 +0800</pubDate>
      <link>https://ruby-china.org/topics/18922</link>
      <guid>https://ruby-china.org/topics/18922</guid>
    </item>
  </channel>
</rss>
