为什么在 Ruby 中做同样的事情有这么多略有不同的方法?

发布于 2024-08-13 06:25:30 字数 275 浏览 5 评论 0原文

我正在学习 Ruby。我的背景是 C++/Java/C#。总的来说,我喜欢这门语言,但我有点困惑为什么有这么多不同的方法来完成同一件事,每种方法都有自己略有不同的语义。

以字符串创建为例。我可以使用 ''、""、q%、Q% 或仅 % 来创建字符串。某些形式支持插值。其他形式允许我指定字符串分隔符。

为什么有五种创建字符串文字的方法?为什么我要使用非插值字符串?与带引号的文字相比,% 语法有什么优势?

我知道 Ruby 中的冗余一定有价值,但我未经训练的眼睛并不能清楚地看到它。请赐教。

I am learning Ruby. My background is C++/Java/C#. Overall, I like the language, but I am a little confused about why there are so many different ways to accomplish the same thing, each with their own slightly different semantics.

Take string creation, for example. I can use '', "", q%, Q%, or just % to create strings. Some forms support interpolation. Other forms allow me to specify the string delimiters.

Why are there five ways to create string literals? Why would I ever use non-interpolated strings? What advantage does the % syntax have over quoted literals?

I know there must be value in the redundency in Ruby, but my untrained eyes are not clearly seeing it. Please enlighten me.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

青丝拂面 2024-08-20 06:25:30

为什么我要使用非插值字符串?

当然,当您不需要插值时。例如,也许您正在输出一些有关字符串插值的文档:

'Use #{x} to interpolate the value of x.'
=> "Use #{x} to interpolate the value of x."

与带引号的文字相比,% 语法有什么优势?

它可以让您更自然地编写字符串,无需引号,或者当您不想转义很多内容时,类似于 C# 的字符串文字前缀 @

%{The % syntax make strings look more "natural".}
=> "The % syntax makes strings look more \"natural\"."

%{<basket size="50">}
=> "<basket size=\"50\">"

还有许多其他 % 表示法:

%w{apple banana #{1}cucumber}   # [w]hitespace-separated array, no interpolation
=> ["apple", "banana", "\#{1}cucumber"]

%W{apple banana #{1}cucumber}   # [W]hitespace-separated array with interpolation
=> ["apple", "banana", "1cucumber"]

# [r]egular expression (finds all unary primes)
%r{^1?$|^(11+?)\1+$}
=> /^1?$|^(11+?)\1+$/

(1..30).to_a.select{ |i| ("1" * i) !~ %r{^1?$|^(11+?)\1+$} }
=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

%x{ruby --version} # [s]hell command
=> "ruby 1.9.1p129 (2009-05-12 revision 23412) [x86_64-linux]\n"

还有 %s (用于符号)和其他一些表示法。

为什么有五种创建字符串文字的方法?

这并不是很不寻常。以 C# 为例,它有几种不同的方法来生成字符串:new String(); <代码>“”; @""; StringBuilder.ToString() 等等。

Why would I ever use non-interpolated strings?

When you don't want the interpolation, of course. For example, perhaps you're outputting some documentation about string interpolation:

'Use #{x} to interpolate the value of x.'
=> "Use #{x} to interpolate the value of x."

What advantage does the % syntax have over quoted literals?

It lets you write strings more naturally, without the quotes, or when you don't want to escape a lot of things, analogous to C#'s string-literal prefix @.

%{The % syntax make strings look more "natural".}
=> "The % syntax makes strings look more \"natural\"."

%{<basket size="50">}
=> "<basket size=\"50\">"

There are many other %-notations:

%w{apple banana #{1}cucumber}   # [w]hitespace-separated array, no interpolation
=> ["apple", "banana", "\#{1}cucumber"]

%W{apple banana #{1}cucumber}   # [W]hitespace-separated array with interpolation
=> ["apple", "banana", "1cucumber"]

# [r]egular expression (finds all unary primes)
%r{^1?$|^(11+?)\1+$}
=> /^1?$|^(11+?)\1+$/

(1..30).to_a.select{ |i| ("1" * i) !~ %r{^1?$|^(11+?)\1+$} }
=> [2, 3, 5, 7, 11, 13, 17, 19, 23, 29]

%x{ruby --version} # [s]hell command
=> "ruby 1.9.1p129 (2009-05-12 revision 23412) [x86_64-linux]\n"

There's also %s (for symbols) and some others.

Why are there five ways to create string literals?

This isn't terribly unusual. Consider C#, for example, which has several different ways to generate strings: new String(); ""; @""; StringBuilder.ToString(), et cetera.

说不完的你爱 2024-08-20 06:25:30

我不是 Ruby 专家,但您听说过“语法糖”这个词吗?基本上,一些编程语言提供不同的语法来完成相同的任务。由于以前的编程/语法经验,有些人可能比其他人更容易找到一种方法。

I'm not a Ruby expert, but had you ever heard the term "syntactic sugar" ? Basically some programing languages offer different syntax to accomplish the same task. Some people could find one way easier than others due to his previous programing/syntax experience.

绝不放开 2024-08-20 06:25:30

在大多数情况下,您最终将使用普通的字符串分隔符。单引号和双引号之间的主要区别在于双引号允许您插入变量。

puts 'this is a string'
# => this is a string
puts "this is a string"
# => this is a string
v = "string"
puts 'this is a #{v}'
# => this is a #{v}
puts "this is a #{v}"
# => this is a string

当您无法使用引号时,%q%Q 非常有用,因为它们是内部字符串的一部分。
例如,您最终可能会写成

html = %Q{this is a <img src="#{img_path}" class="style" /> image tag}

In this case, you can't use double quote as delimiters,除非您想转义内部属性分隔符。此外,您不能使用单引号,因为 img_path 变量不会被插值。

In most situations, you'll end up using normal string delimiters. The main difference between single and double quotes is that double quotes allow you to interpolate variables.

puts 'this is a string'
# => this is a string
puts "this is a string"
# => this is a string
v = "string"
puts 'this is a #{v}'
# => this is a #{v}
puts "this is a #{v}"
# => this is a string

%q and %Q are useful when you can't use quotes because they are part of the internal string.
For example, you might end up writing

html = %Q{this is a <img src="#{img_path}" class="style" /> image tag}

In this case, you can't use double quotes as delimiters unless you want to escape internal attribute delimiters. Also, you can't use single quote because the img_path variable won't be interpolated.

小…楫夜泊 2024-08-20 06:25:30

最初的问题是为什么 Ruby 中有这么多略有不同的做事方式。

有时不同的事情是明智的:引用是一个很好的例子,其中不同的行为需要不同的语法 - 非/插值、交替引用字符等 - 并且历史偶然导致像 %x() 与 `` 这样的同义词,就像在 Perl 中一样。

同义词问题 - [].size [].length [].count - 感觉就像是在一个语言过于随机而 IDE 无法提供帮助的世界中尝试提供帮助:猴子修补和严格的奇怪组合但是动态类型一起使运行时错误成为编码中不可避免且令人沮丧的部分,因此人们尝试通过提供同义词来减少问题。不幸的是,它们最终会让习惯于用不同方法做不同事情的程序员感到困惑。

例如,“如此相似但不完全相同”的问题……

 $ ruby -le 'e=[]; e << (*[:A, :B])'
 -e:1: syntax error, unexpected ')', expecting :: or '[' or '.'
 $ ruby -le 'e=[]; e << *[:A, :B]'
 -e:1: syntax error, unexpected *
 $ ruby -le 'e=[]; e.push(*[:A, :B])'
 $ 

只能真正被视为一个缺陷。每种语言都有它们,但它们通常比这更神秘。

然后,Rubocop 编码标准中出现了简单的任意“使用失败而不是引发,除非您只是重新抛出异常”的废话。

Ruby 中有一些不错的地方,但实际上 - 我宁愿用更有根据的东西进行编码。

The original question is why there are so many slightly different ways of doing things in Ruby.

Sometimes the different things are sensible: quoting is a good case where different behaviour requires different syntax - non/interpolating, alternate quoting characters, etc. - and historical accidence causes synonyms like %x() vs ``, much as in Perl.

The synonym issue - [].size [].length [].count - feels like an attempt to be helpful in a world where the language is too random for IDEs to be able to help: monkey-patching and the weird combination of strict but dynamic typing together make runtime errors an inevitable and frustrating part of the coding, so folks try to reduce the issue by supplying synonyms. Unfortunately, they end up confusing programmers who're accustomed to different methods doing different things.

The 'so similar but not quite' issue, for example ...

 $ ruby -le 'e=[]; e << (*[:A, :B])'
 -e:1: syntax error, unexpected ')', expecting :: or '[' or '.'
 $ ruby -le 'e=[]; e << *[:A, :B]'
 -e:1: syntax error, unexpected *
 $ ruby -le 'e=[]; e.push(*[:A, :B])'
 $ 

... can only really be viewed as a flaw. Every language has them, but they're usually more arcane than this.

And then there's the plain arbitrary 'use fail instead of raise unless you're just rethrowing an exception' nonsense in the Rubocop coding standards.

There are some nice bits in Ruby, but really - I'd far rather be coding in something better-founded.

つ可否回来 2024-08-20 06:25:30

另一个原因是非插值字符串的性能略有提升。使用 '' 与 "" 意味着 Ruby 根本不需要考虑字符串内部的内容。因此,您会看到人们使用单引号作为数组键或符号,因为它们更快。对于它的价值,我将提供一些基准。

require 'benchmark'

Benchmark.bmbm(10) do |x|  
  x.report("single-quote") do
    for z in 0..1000000
      zf = 'hello'
    end
  end  

  x.report("double-quote") do
    for z in 0..1000000
      zf = "hello"
    end
  end  

  x.report("symbol") do
    for z in 0..1000000
      zf = :hello
    end
  end   
end

产量:

Rehearsal ------------------------------------------------
single-quote   0.610000   0.000000   0.610000 (  0.620387)
double-quote   0.630000   0.000000   0.630000 (  0.627018)
symbol         0.270000   0.000000   0.270000 (  0.309873)
--------------------------------------- total: 1.580000sec

One more reason is a minor performance boost for non-interpolated strings. Using '' vs "" means that Ruby doesn't have to consider what's inside the string at all. So you'll see people using single quotes for array keys or symbols because they're faster. For what it's worth I'll include a little benchmark.

require 'benchmark'

Benchmark.bmbm(10) do |x|  
  x.report("single-quote") do
    for z in 0..1000000
      zf = 'hello'
    end
  end  

  x.report("double-quote") do
    for z in 0..1000000
      zf = "hello"
    end
  end  

  x.report("symbol") do
    for z in 0..1000000
      zf = :hello
    end
  end   
end

yields:

Rehearsal ------------------------------------------------
single-quote   0.610000   0.000000   0.610000 (  0.620387)
double-quote   0.630000   0.000000   0.630000 (  0.627018)
symbol         0.270000   0.000000   0.270000 (  0.309873)
--------------------------------------- total: 1.580000sec
開玄 2024-08-20 06:25:30

Ruby 的许多语法都源自 Perl 的语法,例如使用 q 将几个单词引用到字符串中。这可能是品种如此之多的主要原因。

A lot of ruby's syntax is derived from perl's, like using q to quote a few words into a string. That probably is the main reason for such a big variety.

疾风者 2024-08-20 06:25:30

如果您的字符串包含大量特殊字符(如反斜杠、#{} 等)并且您不想转义所有这些字符,您将使用非插值字符串。

如果您的字符串包含大量必须转义的引号,则可以使用不同的分隔符。

如果您的字符串有很多行,这会使正常的字符串语法看起来很笨拙,那么您可以使用heredocs。

You would use non-interpolated strings if your string contains a lot of special characters (like backslashes, #{} etc.) and you don't want to escape all of them.

You'd use different delimiters if your string contains a lot of quotes that you'd otherwise have to escape.

You'd use heredocs if your strings has a lot of lines which would make normal string syntax look unwieldy.

梦境 2024-08-20 06:25:30

Ruby 借鉴了许多语言的结构和思想。两个最明显的影响是 Smalltalk 和 Perl。

根据您对 Smalltalk 或 Perl 的熟悉程度,您很可能选择不同的结构来完成同样的事情。

Ruby borrows constructs and ideas from lots of languages. The two most apparent influences are Smalltalk and Perl.

Depending on your comfort with Smalltalk or Perl you may well choose different constructs to do the same thing.

伪装你 2024-08-20 06:25:30

按照约翰的回答:
在快速黑客攻击中,我经常最终在 ruby​​ 脚本中使用 grep 语法运行 perl 或 sed 单行代码。能够使用 %[ ] 类型语法意味着我可以简单地从终端复制粘贴我的正则表达式

Along the lines of John's answer:
In quick hacks, I often end up running a perl or sed one-liner with grep syntax from within my ruby script. Being able to use %[ ] type syntax means that I can simply copy-paste my regexp from the terminal

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文