常见的 Ruby 习语
我喜欢 ruby 的一件事是,它是一种非常可读的语言(这对于自记录代码非常有用)
但是,受到这个问题的启发:Ruby 代码解释 以及 ||=
如何在 ruby 中工作的描述,我在思考我不使用的 ruby 习惯用法,坦率地说,我并没有完全理解它们。
所以我的问题是,与引用问题中的示例类似,要成为一名真正熟练的 ruby 程序员,我需要了解哪些常见但不明显的 ruby 习惯用法?
顺便说一句,从引用的问题
a ||= b
相当于
if a == nil || a == false
a = b
end
(感谢 Ian Terrell 的更正)
编辑:事实证明这一点并非完全没有争议。 正确的扩展实际上是
(a || (a = (b)))
请参阅以下链接了解原因:
- http://DABlog.RubyPAL.Com/2008/3/25/a-short-circ-edge-case/
- http://DABlog.RubyPAL.Com/2008/3/26/short-circ-post- Correction/
- http://ProcNew.Com/ruby-short-circ-edge-case-response.html
感谢 Jörg W Mittag 指出了这一点。
One thing I love about ruby is that mostly it is a very readable language (which is great for self-documenting code)
However, inspired by this question: Ruby Code explained
and the description of how ||=
works in ruby, I was thinking about the ruby idioms I don't use, as frankly, I don't fully grok them.
So my question is, similar to the example from the referenced question, what common, but not obvious, ruby idioms do I need to be aware of to be a truly proficient ruby programmer?
By the way, from the referenced question
a ||= b
is equivalent to
if a == nil || a == false
a = b
end
(Thanks to Ian Terrell for the correction)
Edit: It turns out this point is not totally uncontroversial. The correct expansion is in fact
(a || (a = (b)))
See these links for why:
- http://DABlog.RubyPAL.Com/2008/3/25/a-short-circuit-edge-case/
- http://DABlog.RubyPAL.Com/2008/3/26/short-circuit-post-correction/
- http://ProcNew.Com/ruby-short-circuit-edge-case-response.html
Thanks to Jörg W Mittag for pointing this out.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(15)
让同一个文件充当库或脚本的神奇 if 子句:
打包和解包数组:
作为方法参数的哈希的语法糖
哈希初始值设定项:
元类语法
类实例变量块
、过程和 lambda。 生活并呼吸它们。
The magic if clause that lets the same file serve as a library or a script:
Packing and unpacking arrays:
The syntatical sugar for hashes as method arguments
Hash initializers:
metaclass syntax
class instance variables
Blocks, procs, and lambdas. Live and breathe them.
这个幻灯片对于主要的 Ruby 习惯用法非常完整,如:
交换两个值:
x, y = y, x
如果未指定,则采用的参数一些默认值
def somemethod(x, y=nil)
将无关参数批量放入数组中
def Replace(re, str, *rest)
如此在...
This slideshow is quite complete on the main Ruby idioms, as in:
Swap two values:
x, y = y, x
Parameters that, if not specified, take on some default value
def somemethod(x, y=nil)
Batches up extraneous parameters into an array
def substitute(re, str, *rest)
And so on...
更多习语:
使用
%w
、%r
和%(
分隔符case 语句中的类型比较
...以及总体滥用case 语句中的
===
方法对于 Ruby 专家来说应该看起来很自然,但对于来自其他语言的人来说可能不是这样:使用
each
来支持for .. in
在 Ruby 1.9+、Rails 中,或者通过修补 Symbol#to_proc 方法,这个正在成为越来越流行的习惯用法:
条件方法/常量定义
查询方法和破坏性(bang)方法
隐式splat参数
Some more idioms:
Use of the
%w
,%r
and%(
delimitersType comparison in case statements
... and overall abuse of the
===
method in case statementsSomething that should look natural to Rubyists, but maybe not so to people coming from other languages: the use of
each
in favor offor .. in
In Ruby 1.9+, Rails, or by patching the Symbol#to_proc method, this is becoming an increasingly popular idiom:
Conditional method/constant definition
Query methods and destructive (bang) methods
Implicit splat parameters
我喜欢这样:
这(大致)相当于:
或者至少这是我用来替换此类块的东西。
I like this:
Which is (roughly) equivalent to:
Or at least that's what I've used to replace such blocks.
我建议阅读流行且设计良好的插件的代码或来自您钦佩和尊重的人的宝石。
我遇到的一些例子:
对应
稍后将被重构为
I would suggest reading through the code of popular and well designed plugins or gems from people you admire and respect.
Some examples I've run into:
corresponding to
which later would be refactored to
That's 微妙地不正确,并且是新手 Ruby 应用程序中错误的来源。
由于(且仅)
nil
和false
的计算结果均为布尔值 false,因此a ||= b
实际上(几乎*)相当于:或者,用另一个 Ruby 惯用法重写它:
(*由于每个语句都有一个值,因此这些语句在技术上并不等同于
a ||= b
。但是如果您不依赖于声明,您不会看到任何差异。)That's subtly incorrect, and is a source of bugs in newcomers' Ruby applications.
Since both (and only)
nil
andfalse
evaluate to a boolean false,a ||= b
is actually (almost*) equivalent to:Or, to rewrite it with another Ruby idiom:
(*Since every statement has a value, these are not technically equivalent to
a ||= b
. But if you're not relying on the value of the statement, you won't see a difference.)以下是从各种来源中精选的一些内容:
使用“unless”和“until”而不是“if not”和“while not”。 不过,当存在“else”条件时,尽量不要使用“unless”。
请记住,您可以一次分配多个变量:
甚至可以在没有临时值的情况下交换变量:
在适当的情况下使用尾随条件,例如,
请注意定义类方法的常用但不是立即显而易见的方法(至少对我来说):
一些参考文献:
Here's a few, culled from various sources:
use "unless" and "until" instead of "if not" and "while not". Try not to use "unless" when an "else" condition exists, though.
Remember you can assign multiple variables at once:
and even swap variable without a temp:
Use trailing conditionals where appropriate, e.g.
Be aware of a commonly-used but not instantly obvious (to me at least) way of defining class methods:
Some references:
我维护一个 wiki 页面,其中涵盖了一些 Ruby 习语和格式:
https://github.com/tokland /tokland/wiki/RubyIdioms
I maintain a wiki page that covers some Ruby idioms and formatting:
https://github.com/tokland/tokland/wiki/RubyIdioms
我总是忘记这个简写 if else 语句的确切语法(以及操作符的名称。有人评论吗?)我认为它在 ruby 之外广泛使用,但如果其他人想要这里的语法,它是:
扩展为
update
调用三元运算符:
return myvar ? myvar.大小:0
I always forget the exact syntax of this shorthand if else statement (and the name of the operator. comments anyone?) I think it's widely used outside of ruby, but in case someone else wants the syntax here it is:
expands to
update
called the ternary operator:
return myvar ? myvar.size : 0
好问题!
正如我认为更直观& 代码越快,我们正在构建的软件就越好。 我将向您展示如何使用 Ruby 在小代码片段中表达我的想法。 在此处了解更多信息
地图
我们可以以不同的方式使用map方法:
或者:
示例
我们可以使用rand方法:
Shuffle:
最惯用的、简单且最简单的方法...示例!
双管道等于/记忆化
正如您在描述中所说,我们可以使用记忆化:
静态方法/类方法
我喜欢使用类方法,我觉得这是一个非常惯用的方法方式来创建& 使用类:
简单。 美丽的。 直觉的。 后台发生了什么?
有关编写惯用 Ruby 代码的更多信息,请阅读此处
Nice question!
As I think the more intuitive & faster the code is, a better software we’re building. I will show you how I express my thoughts using Ruby in little snippets of code. Read more here
Map
We can use map method in different ways:
Or:
Sample
We can use rand method:
Shuffle:
And the idiomatic, simple and easiest way... sample!
Double Pipe Equals / Memoization
As you said in the description, we can use memoization:
Static Method / Class Method
I like to use class methods, I feel it is a really idiomatic way to create & use classes:
Simple. Beautiful. Intuitive. What happens in the background?
For more info to write idiomatic Ruby code, read here
您可以轻松地使用封送对象进行深度复制。 - 摘自《Ruby 编程语言》
You can deepcopy with Marshaling object easily. - taken from The Ruby Programming Language
大致是:
当 b 是一条可能已找到或未找到的记录,并且我需要获取其属性之一时,我使用此选项。
is roughly:
I use this when b is a record which may or may not have been found, and I need to get one of its attributes.
我喜欢如何缩短 If-then-elses 或 case-when 的长度,因为它们返回一个值:
可以重写
同样可以应用于 case-when:
I like how If-then-elses or case-when could be shortened because they return a value:
could be rewriten
The same could be applied to case-when:
用于处理二进制文件的 Array.pack 和 String.unpack:
Array.pack and String.unpack for working with binary files:
方法缺失 magick
如果你调用 ruby 对象中不存在的方法,ruby 解释器将调用名为“method_missing”的方法(如果已定义),你可以使用它来实现一些技巧,例如编写 api 包装器或 dsl,在你不知道的情况下方法和参数名称
method missing magick
if you call methods that not exists in ruby objects, ruby interpreter will call method called 'method_missing' if its defined, you could user this for some tricks, like writing api wrappers, or dsl, where you don;t know all methods and parameters names