For some context, a lot of my code has the same lines of text throughout it (we are using Calabash to do iOS automation, if that gives you an idea).
For example: "all label marked:'#{name}'" is used 8 times in a particular class.
I would prefer to be able to have a constant that uses that text, but if I throw it at the top of the class, of course the variable "name" has not been set yet. Without defining a method that takes a parameter and returns a string, is there a way to do something essentially like this that can exist at the top of the class, but not be evaluated until it's used?:
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
If you use the syntax I mentioned, you get this error: undefined local variable or method `name' for ClassName
A constant doesn't require any special symbol or syntax to declare. You just need to make the first letter an uppercase letter.
A string constant is an arbitrary sequence of characters that are enclosed in single quotation marks (' ').
Creating Strings: To create the string, just put the sequence of characters either in double quotes or single quotes. Also, the user can store the string into some variable. In Ruby, there is no need to specify the data type of the variable.
A string constant is enclosed in double quotation marks ("). Any ASCII character is a valid character in a constant string.
You could use String#% to insert the string later.
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"
I agree with @Sergio. Don't define a constant string that includes a variable. Just use a method. Including a variable in a constant seems like a bad idea. Constants shouldn't be dynamic, by definition.
If you really want to include a variable in a constant string, you can assign a lambda to a contstant, like so:
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
I removed the @
before the constant, since including it creates a class-level instance variable, not a constant.
I really wouldn't use the code sample I posted, though. Just use a method. Avdi Grimm has a good post called "Do we need constants?" where he describes some of the benefits of using methods instead of constants.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With