在Ruby中定义涉及变量的常量字符串的最简洁方法是什么?

时间:2013-11-04 18:30:50

标签: ruby calabash

对于某些上下文,我的很多代码都有相同的文本行(我们使用Calabash进行iOS自动化,如果这给你一个想法)。

例如:“标记的所有标签:'#{name}'”在特定类别中使用了8次。

我希望能够有一个使用该文本的常量,但是如果我把它放在类的顶部,当然变量“name”还没有设置。如果没有定义一个接受参数并返回字符串的方法,有没有办法做一些本质上可以存在于类顶部的东西,但在使用它之前不进行评估?:

class ClassName
  extend Calabash::Cucumber::Operations

  @NAME_CONSTANT = "all label marked:'#{name}'"

  def self.method_name(name)
    query("#{@NAME_CONSTANT} sibling label marked:'anotherLabel' isHidden:0")
  end
end

如果你使用我提到的语法,你会收到这个错误:未定义的局部变量或类名的方法`name'

3 个答案:

答案 0 :(得分:1)

我同意@Sergio。 不要定义包含变量的常量字符串。只需使用方法。将变量包含在常量中似乎是一个坏主意。根据定义,常量不应是动态的。

如果确实想要在常量字符串中包含变量,则可以将lambda分配给常量,如下所示:

class ClassName
  extend Calabash::Cucumber::Operations

  NAME_CONSTANT = ->(name) { "all label marked:'#{name}'" }

  def self.method_name(name)
    query("#{NAME_CONSTANT.call(name)} sibling label marked:'anotherLabel' isHidden:0")
  end
end

我在常量之前删除了@,因为包含它会创建一个类级实例变量,而不是常量。

确实不会使用我发布的代码示例。只需使用一种方法。 Avdi Grimm有一个很好的帖子叫做“Do we need constants?”,他描述了使用方法而不是常量的一些好处。

答案 1 :(得分:1)

您面临的基本问题是字符串插值在解释文字时发生,任何引用变量的范围由代码中字符串的位置决定。

如果将插值字符串放在方法中,则它将无法访问字符串中使用的任何变量的本地定义。您必须传入所使用的任何变量的值,如:

def name_constant(name)
  "all label marked:'#{name}'"
end

或者,您需要将“常量”声明为未解释的字符串,如下所示:

@name_constant = '"all label marked:''#{name}''"'

然后在引用时解释它,如下所示:

eval(@name_constant)
顺便说一下,我忽略了这个问题并不是真正的“常量”,而是使用实例变量和类变量。

答案 2 :(得分:1)

您可以稍后使用String#%插入字符串。

class ClassName
    @NAME_CONSTANT = "all label marked:'%{name}'"

    def self.method_name(insert_name)
        query("#{@NAME_CONSTANT} sibling label marked:'anotherLabel' isHidden:0" % {name: insert_name})
    end

    def self.query(string)
        puts string
    end 
end 

ClassName.method_name('test')
#=> "all label marked:'test' sibling label marked:'anotherLabel' isHidden:0"