奇怪的 Ruby

栏目: Ruby · 发布时间: 5年前

内容简介:最近我为 prettier 写了一个 Ruby 版本的插件Ruby 中的 case 表达式与其他语言的 Switch 语句非常相似,它们提供基于一个值来处理不同逻辑分支的方法。但你也可以使用没有谓词的 case 表达式,这在功能上等同与检查

最近我为 prettier 写了一个 Ruby 版本的插件 plugin for prettier ,在过程中我发现 Ruby 语言中很多奇怪的地方(通过需要考虑 AST 的每个节点类型以及结构的每个变体),我发现一些有趣的事情,并在这里与你分享。

case

Ruby 中的 case 表达式与其他语言的 Switch 语句非常相似,它们提供基于一个值来处理不同逻辑分支的方法。但你也可以使用没有谓词的 case 表达式,

case
when foo == 1
  ...
when bar == 2
  ...
end

这在功能上等同与检查 if foo == 1 和 elsif bar == 2

flip-flops

Flip-flops(名称来自电路设计)是最难懂的操作符之一。 这篇文章 有一个很好的解释。

lines.each do |line|
  next unless (line =~ start_pattern)..(line =~ end_pattern)

  puts line
end

基本上,这将遍历一些列表 lines ,打印满足开始和结束时间条件的每一个行。

for 循环

你知道 Ruby 还有 for 循环吗?他们看起来像这样:

for num in [1, 2, 3] do
  puts num
end

这也意味着 in 是一个保留字,所以你也不能将其用作标识符。

hooks

Ruby 有两个特殊的 Block 块,它们内置在语言中让你可以 hook 脚本的开始和退出。我认为它们对于脚本编写特别有用,而对于应用程序级逻辑则不那么有用。他们看着像是:

BEGIN {
  puts 'script has started'
}

END {
  puts 'script has ended'
}

有趣的是这些 Block 不支持 do...end 写法,我不知道为什么。

数字

在 Ruby 中二进制,八进制和十六进制数字有一种特殊的语法表示,以下所有语句的值都为 true:

0b10 == 2   # 二进制
0o10 == 8   # 八进制
0x10 == 16  # 十六进制

最重要的是,您甚至可以删除八进制数重点额 o 而使用前缀 0010 == 8 即为 true,如果不小心这个可能很容易出现意想不到的问题!

procs

Procs 和 lambdas 都有一个使用方括号调用的特殊语法,比如:

add = ->(left, right) { left + right }
add[3, 4] # => 7

传递给方括号的参数数量与传递给 proc 的数量一致。因此,对于没有元素的 proc 或 lambdas,您可以完全去掉参数,如:

greet = -> { puts 'Hello, world!' }
greet[]

字符串

字符串有各种有趣的属性!下面是一些让我感到惊讶的事情。

%x 字面量

您可能知道反引号表达式(即 ls ),它将生成一个进程在 shell 中执行,然后将 stdio 输出返回给调用者。(要小心请不要自己 RCE)

你可能不知道 %x 字面量,它们实际上是同一个东西(即 %x[ls] )。不要与其他 %-字面量 混淆,像 %w%i 创建数组!

%q 字面量

你可以使用 %q%Q 来创建一个字符串字面量(比如 %q[abc] )。这实际上和使用单引号和双引号是一样的,区别是后者不需要对双引号进行转移,非常方便。

插值

Ruby 中正常的字符串插值看起来像这样 "a #{b} c" ,其中 b 是会响应 to_s 的变量( 即除 BasicObject 之外的任何东西 )。但是你知道如果像插入一个实例(instance)、类或全局变量可以不用大括号,也就是下面的代码完全有效:

@instance = 'instance'
@@class = 'class'
$global = 'global'

"#@instance #@@class #$global" == 'instance class global' # => true

它甚至可以在正则表达式中使用!如果用上面的表达式中的 / 替换双引号,你将获得带有插值变量的正则表达式。

? 字面量

我之所以把最好的留到最后,因为这真的是挺奇怪,以下两个语句在 Ruby 中都有效:

?a == 'a'
?\M-\C-a == "\x81"

事实证明 ? 允许您创建长度为 1 的字符串,并引入一些特殊的附加功能。有关进一步说明,请直接从 Ruby 文档中获取:

\cx or \C-x    控制字符,其中 x 是一个可打印的 ASCII 字符
\M-x           元字符,其中 x 是一个可打印的 ASCII 字符
\M-\C-x        元控制字符,其中 x 是一个可打印的 ASCII 字符
\M-\cx         如上
\c\M-x         如上
\c? or \C-?    删除,ASCII 7Fh (DEL)

void

在Ruby中,您可以使用 () 来表示 nil ,因为它被视为没有语句的空表达式。这导致能够做各种奇怪的事情,比如 !() ,其值为 true

tl;dr

Ruby非常具有表现力,它为您提供了许多方法。这与许多语言形成了鲜明的对比(例如,在 Python 之蝉 (The Zen of Python) 中,它指出 “应该有一种 - 最好只有一种 - 显而易见的方式”)。

当然这种方法有权衡。虽然它可以为您提供快速生产代码的能力,但如果有无数相似的处理方法,它也会降低阅读效率。这是 prettier 和其 Ruby 插件的明确目标之一 - 我们正在尝试标准化,以便您可以回到编写应用程序代码之中。


以上所述就是小编给大家介绍的《奇怪的 Ruby》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

实现领域驱动设计

实现领域驱动设计

Vaughn Vernon / 滕云 / 电子工业出版社 / 2014-3 / 99.00元

领域驱动设计(DDD)是教我们如何做好软件的,同时也是教我们如何更好地使用面向对象技术的。它为我们提供了设计软件的全新视角,同时也给开发者留下了一大难题:如何将领域驱动设计付诸实践?Vaughn Vernon 的这本《实现领域驱动设计》为我们给出了全面的解答。 《实现领域驱动设计》分别从战略和战术层面详尽地讨论了如何实现DDD,其中包含了大量的最佳实践、设计准则和对一些问题的折中性讨论。《实......一起来看看 《实现领域驱动设计》 这本书的介绍吧!

JSON 在线解析
JSON 在线解析

在线 JSON 格式化工具

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

RGB CMYK 转换工具
RGB CMYK 转换工具

RGB CMYK 互转工具