我理解如下:

$ ruby -e "p 'abc'.sub('a','A').sub('b', 'B')"
"ABc"

我也同意以下几点:

echo abc | ruby -p -e "sub('a','A');sub('b', 'B')"
ABc

但是:

echo abc | ruby -p -e "sub('a','A').sub('b', 'B')"
Abc

我希望结果也是"ABc",为什么不是呢?第二个sub('b', 'B')不工作.

推荐答案

这两种情况看起来很相似,但实际上您运行的方法与其中的Ruby core库不同:

在第一种情况下,即sub('a','A');sub('b', 'B'):

运行这两个sub时没有指定显式接收器,因此调用方法Kernel#sub.Ruby文档介绍了这种方法:

sub(pattern, replacement)$_

相当于$_.sub(args),但如果发生替换,将更新$_.仅当指定了-p/-n命令行选项时可用.

因此,在第一个示例中,您实际上调用了Kernel#sub次,每次调用之后,$_都会更新.因此,$_是在执行了第二sub之后的ABc.在-e提供的整个表达式的末尾(即在-p选项提供的隐式循环的末尾),打印$_的值,您可以看到ABc.

在第二个示例中,即.

sub('a','A').sub('b', 'B')

与之前一样,第一个sub也是Kernel#sub.它可以将字符串转换为Abc,也可以将$_设置为Abc.然而,第二sub现在确实具有显式接收器(由第一sub产生的字符串),并且在这种情况下,执行方法String#sub.此方法生成ABc,但与Kernel#sub不同,它执行not更新$_.因此,$_仍然设置为Abc,这就是您所看到的输出.

Ruby相关问答推荐

PDFNet:Ubuntu 16.04 和 Ubuntu 20.04 上 PDF 输出文本的词序不同

ASDF 上缺少 Ruby 版本

整数除以负数

使用 RSpec 存根 Time.now

何时在 Ruby 方法中使用 `self.foo` 而不是 `foo`

Ruby:子字符串到一定长度,也到子字符串中的最后一个空格

确保如何在 ruby​​ 中工作

ruby 是否支持 case 语句中的范围?

为什么我们要在 Ruby 的类中放置一个模块?

Ruby 中的抽象方法

对于基于 GitHub 的 gem,强制Bundle 安装使用 https:// 而不是 git://

错误:Windows 的 SASS 安装

Ruby 1.9:如何正确大写和小写多字节字符串?

在 Ruby 中查找内存泄漏的原因

Ruby:除非与如果不是

哪个键/值存储最有前途/最稳定?

获取Ruby中当前目录的父目录

判断整数是否在范围内

Ruby 是否有像栈、队列、链表、映射或集合这样的容器?

如何在 Ruby 中找到字符串中字符的索引?