“#{}”表示法与 erb 表示法

发布于 2024-10-31 15:14:34 字数 749 浏览 3 评论 0原文

符号之间有什么区别:

"
  some text
  #{some_ruby_code}
  some text
  #{some_more_ruby_code}
  some_other_text
"

ERB.new("
  some text
  <%=some_ruby_code%>
  some text
  <%=some_more_ruby_code%>
  some_other_text
").result

只是有一个广泛的印象,即 erb 符号可能更强大,但不太清楚。您能否从各个方面进行比较,并告诉我们在什么样的场合应该使用它们?哪些事情可以用一种表示法完成,而不能用另一种表示法完成?

补充 1

到目前为止,大多数答案似乎都声称 erb 效率低下,并且在可以使用 "#{ }" 时不应使用 erb 。现在,我们换个方式问。为什么 "#{ }" 符号不能代替 erb?难道不是更快更好吗?

添加 2

下面的大多数答案似乎都假设 "#{ }" 的单次出现不会跨越多行,因此像循环这样的代码块不能嵌入多行。但为什么不呢?如果您这样做,我认为与使用 <% > 没有任何区别,除了在后者中您将 <% > 放在每个线。

What are the differences between the notation:

"
  some text
  #{some_ruby_code}
  some text
  #{some_more_ruby_code}
  some_other_text
"

and

ERB.new("
  some text
  <%=some_ruby_code%>
  some text
  <%=some_more_ruby_code%>
  some_other_text
").result

I just have a broad impression that the erb notation may be more powerful, but am not so clear. Can you compare them from various aspects, and tell which should be used in what kind of occasions? What kinds of things can be done in one notation and not in the other?

Addition 1

Most of the answers so far seem to be claiming how erb is inefficient, and shouldn't be used when "#{ }" can be used. Now, let's ask the other way. Why can't the "#{ }" notation replace erb? Wouldn't it be much faster and better?

Addition 2

Most answers below seem to be assuming that a single occurance of "#{ }" does not span over multiple lines, so that a chunk of code like a loop taking multiple lines cannot be embedded within. But why not? If you do so, I don't see any difference from doing it with <% >, except that in the latter you put <% > in every line.

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

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

发布评论

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

评论(3

来世叙缘 2024-11-07 15:14:34

你是对的,你的 ERB 版本应该产生与普通版本相同的结果(我认为),但其目的完全不同。

ERB 实际上只是用于模板化:如果您需要生成文本(如 HTML 页面或文档),像 ERB 这样的模板引擎将是正确的工具。不过,它并不是用于简单的字符串插值:虽然它确实能够做到这一点,但这是一种相当迂回的方式。事实上,您实际上是从字符串创建一个 ERB 对象,然后将其计算回字符串。

您可以通过快速基准测试来了解这是多么低效:

$ irb -rbenchmark -rerb
ruby-1.9.2-p136 :023 > Benchmark.bm do |bm|
ruby-1.9.2-p136 :024 >     bm.report 'interpolation' do
ruby-1.9.2-p136 :025 >       a = 'hello there'
ruby-1.9.2-p136 :026?>     5000.times { "well #{a}" }
ruby-1.9.2-p136 :027?>     end
ruby-1.9.2-p136 :028?>   bm.report 'erb' do
ruby-1.9.2-p136 :029 >       a = 'hello there'
ruby-1.9.2-p136 :030?>     5000.times { ERB.new("well <%= a %>").result(binding) }
ruby-1.9.2-p136 :031?>     end
ruby-1.9.2-p136 :032?>   end
      user     system      total        real
interpolation  0.000000   0.000000   0.000000 (  0.001495)
erb  0.340000   0.000000   0.340000 (  0.352098)
 => true 

将 Ruby 代码插入字符串的标准方法是在字符串文字中使用 #{}。这是内置在语言级别的(而不是级别)。

You're right that your ERB version should produce the same result as the normal version (I think), but its purpose is entirely different.

ERB is really just for templating: if you need to generate text (like an HTML page, or a document), some templating engine like ERB will be the right tool. It's not meant for simple string interpolation, though: while it certainly is capable of doing that, it's a rather periphrastic way of going about it. Indeed, you're actually creating an ERB object from a string, and then evaluating it back into a string.

You can get an idea of how very inefficient this is with a quick benchmark:

$ irb -rbenchmark -rerb
ruby-1.9.2-p136 :023 > Benchmark.bm do |bm|
ruby-1.9.2-p136 :024 >     bm.report 'interpolation' do
ruby-1.9.2-p136 :025 >       a = 'hello there'
ruby-1.9.2-p136 :026?>     5000.times { "well #{a}" }
ruby-1.9.2-p136 :027?>     end
ruby-1.9.2-p136 :028?>   bm.report 'erb' do
ruby-1.9.2-p136 :029 >       a = 'hello there'
ruby-1.9.2-p136 :030?>     5000.times { ERB.new("well <%= a %>").result(binding) }
ruby-1.9.2-p136 :031?>     end
ruby-1.9.2-p136 :032?>   end
      user     system      total        real
interpolation  0.000000   0.000000   0.000000 (  0.001495)
erb  0.340000   0.000000   0.340000 (  0.352098)
 => true 

The standard way to interpolate Ruby code into strings is using #{} within a string literal. This is built in at the language level (as opposed to at the library level).

神也荒唐 2024-11-07 15:14:34

ERB 的优点:

  1. 每个人都已经知道并“喜欢”类似 PHP 的风格
  2. 您无需担心平衡或转义 '"
  3. 通常您不需要对底层 Ruby 机制进行编程,即,您不需要定义一个方法,可能位于一个类中,可能用一个模块限定,等等......

从大的角度来看,我相信总体的想法是分离出程序中需要由软件开发人员完成的部分与前端 Web 开发人员可以完成的部分例如,软件开发人员可以简单地指定 @account_number 可用并且它可以。 。

在现实生活中,似乎有很多单人项目,但至少在某个时候,规范是让一个团队解决一个典型问题,即使在今天,看看所有的 Rails 显然,开发人员对 Ruby 几乎一无所知,而且 ERB 早于 Rails,所以如果你回到该机制的起源,有一段时间你真的总是需要一个真正的软件部门,因为每个项目都涉及构建一个框架,因此您可能不希望团队中的每一位成员都具备 Ruby 软件资格。

现在,我明白你的意思了。如果您已经了解 Ruby,那么就很难证明 erb 的丑陋是合理的。

Advantages to ERB:

  1. Everyone already knows and "loves" that PHP-like style
  2. You don't need to worry about balancing or escaping ' or "
  3. Typically you don't need to program the underlying Ruby mechanism, i.e., you don't need to define a method, possibly located in a class, perhaps qualified with a module, etc...

In the big picture, I believe the overall idea is to separate out the parts of a program that need to be done by a software developer from the part that a front-end web developer can do. For example, the software developer can simply specify that @account_number is available and it can be referenced by HTMLers without Ruby qualifications.

In real life, there seem to be a lot of one-person projects, but at least at one time the norm was to throw a team at a typical problem. Even today, look at all the Rails questions here on SO from developers that obviously know hardly any Ruby. And ERB predates Rails, so if you go back to the origins of the mechanism there was a time you really always needed a real software department because every project involved putting together a framework, so you probably didn't want to require Ruby software qualifications from every last member on the team.

Now, I do see what you mean. If you already know Ruby it's a lot harder to justify the erb ugliness.

痞味浪人 2024-11-07 15:14:34

尝试使用 ERB 进行一般字符串插值的一个缺点是 ERB 实际上旨在生成 HTML。当您忘记对所有内容进行原始化并且对为什么与号、大于号、小于号等符号被破坏感到困惑时,结果将是许多编码问题。

我认为 ERB 也会有更多的计算开销,但这可能并不重要。

此外,如果您将内联 ERB 放入 Ruby 中,最终将导致 Ruby inside ERB inside Ruby(当您从 ERB 中调用方法时,很可能会出现更多级别),这将是一个令人困惑的混乱。想想那些必须维护你的代码的可怜的灵魂,说可怜的灵魂甚至可能就是你。

更新:您可以使用 #{} 来创建简单的 HTML 模板(请参阅 Mustache 之类的东西)但是制作重复的部分会很困难而且相当难看;重复的部分在 HTML 模板中很常见,因此对于 HTML 模板系统来说应该是简单和自然的。使用 ERB,您可以:

<% a.each do |e| %>
    <!-- ... -->
<% end %>

但这会使 #{} 插值变得一团糟。您最终还会一直执行#{html(blahblah)},而大多数人会忘记。

此外,“#”在 URL 中具有特殊含义,在 CSS 中具有不同的特殊含义(其中大括号也具有特殊含义);片段 URL 和 CSS 块在 HTML 模板中相当常见,因此您会经常担心混淆。当使用 #{} 生成 CSS 选择器或 URL 中的片段时,这种特殊的麻烦可能只会成为问题,但这足以使其变得麻烦。

One downside of trying to use ERB for general string interpolation is that ERB is really aimed at generating HTML. The result will be lots of encoding issues when you forget to raw-ify everything and get confused about why your ampersands, greater-than, less-than, etc. symbols are getting mangled.

I think there'll be more computational overhead for ERB as well but this might not matter.

Furthermore, if you put inlined ERB inside Ruby will end up with Ruby inside ERB inside Ruby (and quite possibly more levels as you call methods from within ERB) and that will be a bit of a confusing mess. Think of the poor souls that will have to maintain your code, said poor soul might even be you.

UPDATE: You could use #{} for simple HTML templates (see Mustache for something like that) but it would be difficult and rather ugly to produce a repeated section; repeated sections are quite common in HTML templates so that should be easy and natural for an HTML template system. With ERB, you can just:

<% a.each do |e| %>
    <!-- ... -->
<% end %>

but that would be a mess in #{} interpolation. You'd also end up doing #{html(blahblah)} all the time and most people would forget.

Also, "#" has a special meaning in URLs and a different special meaning in CSS (where braces also have a special meaning); fragment URLs and chunks of CSS are fairly common in HTML templates so you'd be constantly worrying about mixing up things up. This particular bit of nastiness would probably only be an issue when using #{} to produce a CSS selector or a fragment in a URL but that's enough to make it cumbersome.

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