0

可能重复:
Ruby 中#{ } 的含义?

我知道它是用于元编程的,我很难理解这个操作符在下面的例子中做了什么:

class Class
 def attr_accessor_with_history(attr_name)
    attr_name = attr_name.to_s # make sure it's a string
    attr_reader attr_name
    attr_reader attr_name+"_history"
    class_eval %Q"
        def #{attr_name}=(value)
            if !defined? @#{attr_name}_history
                @#{attr_name}_history = [@#{attr_name}]
            end
            @#{attr_name} = value
            @#{attr_name}_history << value
        end
    "
    end
end

class Foo
   attr_accessor_with_history :bar
end
4

4 回答 4

2

一般而言,#{...}评估其中的任何内容并将其返回,转换为带有to_s. 这使得在一个字符串中组合几个东西变得容易得多。

一个典型的例子:

"There are #{n} car#{n == 1 ? '' : 's'} in the #{s}"

这相当于:

"There are " + n.to_s + " car" + (n == 1 ? '' : 's').to_s + " in the " + s.to+_s

重要的是要记住,#{...}插值的内容实际上是一段 Ruby 代码,其结果将在组合之前转换为字符串。

元编程的那个例子非常懒惰,因为可以使用并且instance_variable_get可以避免。大多数时候,您会看到用于创建字符串的字符串插值,而不是方法或类。instance_variable_seteval

该方法有一个更强大的格式化程序String#%

"There are %d car%s in the %s" % [ n, (n == 1 ? '' : 's'), s ]

这可用于添加精确的小数位数、用空格填充字符串和其他有用的东西。

于 2013-02-03T02:14:04.210 回答
1

#{var}在 Ruby 中进行变量替换。例如:

var = "Hello, my name is #{name}"

您发布的代码正在生成一个字符串,其中包含您传入的 attr_name 的访问器方法的代码。

于 2013-02-03T01:52:13.990 回答
0

它并没有真正做太多:D。所有的红色文本基本上只是一个字符串。“bla #{var} bla”部分只是写“bla”+ var +“bla”的更好方式。在 irb 中自己尝试一下:

a = 10
puts "The Joker stole #{a} pies." 
于 2013-02-03T01:52:24.870 回答
0

它所做的就是所谓的variable interpolation

name = "Bond"
p "The name is #{name}. James #{name}."

将输出,

> "The name is Bond. James Bond."
于 2013-02-03T02:32:27.580 回答