I want to insert the following as the value for a variable in some Ruby:
`~!@#$%^&*()_-+={}|[]\\:\";\'<>?,./
Surrounding this in doub
<<EOT
, and %q{}
are your friends. Info on using them from the Programming Ruby
The Pragmatic Programmer's Guide.
Try mixing the various approaches:
%q{`~!@#$%^&*()_-+}+"{}"+%q{=|[]\\:";'<>?,./}
or alternatively, just use backslashes to escape the problematic chars:
"`~!@\#$%^&*()_-+{}=|[]\\:\";'<>?,./"
First, unless I'm crazy %q()
does work here, perfectly well, since the inner parentheses are balanced:
>> weird = %q(`~!@#$%^&*()_-+={}|[]\:";'<>?,./)
=> "`~!@\#$%^&*()_-+={}|[]\\:";'<>?,./"
>> puts weird
`~!@#$%^&*()_-+={}|[]\:";'<>?,./
As a side note: when using %q
, you always have the nuclear option of using spaces as the delimiter. This is foul and officially a Bad Idea, but it works.
Again, I wouldn't do it, but just to see...
>> weird = %q `~!@#$%^&*()_-+={}|[]\:";'<>?,./
=> "`~!@\#$%^&*()_-+={}|[]\\:";'<>?,./"
Don't use multiple methods - keep it simple.
Escape the #, the backslash, and the double-quote.
irb(main):001:0> foo = "`~!@\#$%^&*()_-+={}|[]\\:\";'<>?,./"
=> "`~!@\#$%^&*()_-+={}|[]\\:\";'<>?,./"
Or if you don't want to escape the # (the substitution character for variables in double-quoted strings), use and escape single quotes instead:
irb(main):002:0> foo = '`~!@#$%^&*()_-+={}|[]\\:";\'<>?,./'
=> "`~!@\#$%^&*()_-+={}|[]\\:\";'<>?,./"
%q is great for lots of other strings that don't contain every ascii punctuation character. :)
%q(text without parens)
%q{text without braces}
%Q[text without brackets with #{foo} substitution]
Edit: Evidently you can used balanced parens inside %q() successfully as well, but I would think that's slightly dangerous from a maintenance standpoint, as there's no semantics there to imply that you're always going to necessarily balance your parens in a string.
The first thing I'd normally think of would be a %q directive -- but since you seem to be using all the punctuation you'd normally use to delimit one, I can't think of an easy way to make it work here.
The second thing I'd think of would be a heredoc:
mystring = <<END
`~!@#$%^&*()_-+={}|[]\:";'<>?,./
END
That breaks after the backslash, though.
So my third answer, clunky but the best thing I can think of with just two minutes' thought, would be to substitute something harmless for the "problem" characters and then substitute it after the assignment:
mystring = '`~!@#$%^&*()_-+={}|[]\:"; <>?,./'.tr(" ","'")
I don't like it, but it works.