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

mkh04yzy  于 12个月前  发布在  Ruby
关注(0)|答案(9)|浏览(146)

我正在学习Ruby。我的背景是C++/Java/C#。总的来说,我喜欢这门语言,但我有点困惑,为什么有这么多不同的方法来完成同一件事,每一种方法都有自己的略有不同的语义。
以字符串创建为例,我可以使用''、“"、q%、Q%或仅使用%来创建字符串。有些形式支持插值。其他形式允许我指定字符串分隔符。
为什么有五种方法来创建字符串字面量?为什么我会使用非插值字符串?%语法比引用字面量有什么优势?
我知道Ruby中的冗余一定有价值,但我的眼睛没有经过训练,看不清楚。请启发我。

aydmsdu9

aydmsdu91#

我为什么要使用非插值字符串?
当然,当你不想要插值的时候。例如,也许你正在输出一些关于字符串插值的文档:

'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()等等。

iqxoj9l9

iqxoj9l92#

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

myzjeezk

myzjeezk3#

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

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}


在这种情况下,你不能使用双引号作为分隔符,除非你想转义内部属性分隔符。同样,你不能使用单引号,因为img_path变量不会被插值。

kkbh8khc

kkbh8khc4#

最初的问题是为什么Ruby中有这么多稍微不同的做事方式。
有时不同的东西是明智的:引用是一个很好的例子,不同的行为需要不同的语法-非/插值,交替引用字符等-和历史accidence导致同义词,如%x()vs ``,很像Perl。
同义词问题- [].size [].length [].count -感觉像是在一个语言太随机而IDE无法提供帮助的世界中尝试提供帮助:monkey-patching和严格但动态类型的奇怪组合使运行时错误成为编码中不可避免和令人沮丧的部分,因此人们试图通过提供同义词来减少问题。不幸的是,它们最终会使习惯于用不同方法做不同事情的程序员感到困惑。
例如,“相似但不完全”的问题...

$ 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编码标准中,还有一个简单的任意性,即“使用fail而不是raise,除非你只是重新抛出一个异常”。
Ruby中有一些很好的地方,但实际上-我宁愿在更好的基础上编码。

gjmwrych

gjmwrych5#

另一个原因是对非插值字符串的性能有轻微的提升。使用"vs“”意味着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

35g0bw71

35g0bw716#

ruby的很多语法都是从perl的语法衍生而来的,比如使用q将几个单词引用到一个字符串中,这可能是ruby有如此大变化的主要原因。

5cnsuln7

5cnsuln77#

如果你的字符串包含很多特殊字符(如反斜杠,#{}等),你可以使用非插值字符串,并且你不想转义所有的字符。
如果字符串中包含大量引号,则必须使用不同的分隔符。
如果你的字符串有很多行,这会使普通的字符串语法看起来很笨拙,你可以使用heredocs。

sg2wtvxw

sg2wtvxw8#

Ruby借鉴了许多语言的结构和思想,其中最明显的两个影响是Smalltalk和Perl。
根据您对Smalltalk或Perl的熟悉程度,您可以选择不同的结构来做同样的事情。

vzgqcmou

vzgqcmou9#

沿着John的回答:在快速破解中,我经常在我的ruby脚本中使用grep语法运行perl或sed一行程序。能够使用%[ ]类型语法意味着我可以简单地从终端复制粘贴regexp

相关问题