Freemarker ruby script template issue - ruby

So I am trying to run a ruby script and I have string expansion sections that are being mistaken for freemarker expressions, for example:
puts "Foo bar baz quux #{#awesome}"
In ruby the #{} is valid ruby, and I need Freemarker to ignore it. According to the documentation, I can escape lie this:
#\{#awesome}
But that leaves the backslash in the final output. I tried to do this:
#{r"#{#awesome"}}
But I get an exception saying that a number was expected... According to the docs, this should produce a literal '#{#awesome}'
What gives? Am I doing something wrong?

This will work:
${r"#{#awesome"}}
Your attempt gives error because FreeMarker's #{...} only accepts numbers.

Related

String operations and `eval`

I have an AWS lambda function that receives user's code from a browser as a string and runs eval in a sandboxed environment as in a standard REPL. I am not trying to interpolate a string. I am trying to have eval recognize and perform operations on strings.
I am somewhat limited in the operations I can perform. Basic regex replacement is cool, but I don't think I would be able to do anything more involved than that, but perhaps I'm mistaken.
This works for basic arithmetic operations, the creation of class instances, etc. However, it fails to perform string operations properly. When I pass:
eval `("3*4")`
it returns 12, which is great. However, if I pass:
eval(""str:" + " test"")
it fails to return "str: test". In fact it returns nothing.
It has been suggested that I escape the double quotes. In a REPL, replacing all double quotes with escaped ones, such as \", works.
eval("\"str \" + \"test\"") # => "str test"
However, when I try this with AWS, it returns "\"str \" + \"test\"".
I look forward to hearing your responses.
You shouldn't expect eval(""str:" + " test"") to work. The problem is not related to AWS lambda. If you try this on your own machine, using pry or irb, you will get a SyntaxError. That's because your interpreter can't understand that you are only passing one unified string to eval. So you need to escape all quotation marks inside your string:
eval("\"str \" + \"test\"")
If you have tested it in a REPL without escaping, and it worked, it seems that the REPL you are using, somehow changes your input before sending it to interpreter.
I have seemed to find a work around.
To begin, I will first clarify what my issue was. Say a user entered the following:
class Test
attr_accesssor :data
def initialize(data = nil)
#data = data
end
end
Followed by
Test.new(4).data
eval would properly return 4.
Now say, however, that the user instead wrote
Test.new("A nice, fine string").data
eval would return nothing.
I noticed, however, that if I tacked on a .inspect, as shown below:
Test.new("A nice, fine string").data.inspect
I would be returned A nice, fine string.
So my solution was to wrap the entirety of the user's code in parenthesis and then call .inspect.
Which was accomplished by the following line
code = "(" << code << ").inspect"
Thank you to everyone who took the time to help me out. I really appreciate all of the feedback and suggestions.
You need to be careful about string interpolation when using eval on strings:
str = %(This is my String. It's name is string. Now I can eval "Hooray for my string")
eval(str.inspect)
#=> "This is my String. It's name is string. Now I can eval \"Hooray for my string\""
however these will raise errors
eval(str)
#=> SyntaxError: (eval):1: unterminated string meets end of file
eval(puts str) # will output the string but raise an error after it.
#=> This is my String. It's name is string. Now I can eval "Hooray for my string"
# TypeError: no implicit conversion of nil into String
but this will work
eval("puts #{str.inspect}")
#=> This is my String. It's name is string. Now I can eval "Hooray for my string"

Errors in parsing escaped double quotes with json parsers

How would one parse a JSON string like this:
"[{\"something\": \"information \"YES\"\", \"next\": \"normal\"}]"
I've used both the json gem and the Oj gem but they both run into errors. I've also tried using eval() on it.
I've also tried using different regexes to target the quotes surrounding YES and replacing them with single quotes but I haven't been successful in figuring one out.
The string you posted isn't valid JSON. This would be the non-stringified JSON:
[{"something":"information \"YES\"","next":"normal"}]
Note that the escaping is still present in the value for something.
If you had this JSON as a string, the double-quote escaping depends on the language you're working in. In Ruby, this is what it looks like:
"[{\"something\":\"information \\\"YES\\\"\",\"next\":\"normal\"}]"
If you use that, you'll be able to parse it just fine:
JSON.parse("[{\"something\":\"information \\\"YES\\\"\",\"next\":\"normal\"}]")
#=> [{"something"=>"information \"YES\"", "next"=>"normal"}]

Ruby: Why do I get warning "regex literal in condition" here?

A simple Ruby program, which works well (using Ruby 2.0.0):
#!/usr/bin/ruby
while gets
print if /foo/../bar/
end
However, Ruby also outputs the warning warning: regex literal in condition. It seems that Ruby considers my flip-flop-expression /foo/../bar/ as dangerous.
My question: Where lies the danger in this program? And: Can I turn off this warning (ideally only for this statement, keeping other warnings active)?
BTW, I found on the net several discussions of this kind of code, also mentioning the warning, but never found a good explanation why we get warned.
You can avoid the warning by using an explicit match:
while gets
print if ~/foo/..~/bar/
end
Regexp#~ matches against $_.
I don't know why the warning is shown (to be honest, I wasn't even aware that Ruby matches regexp literals against $_ implicitly), but according to the parser's source code, it is shown unless you provide the -e option when invoking Ruby, i.e. passing the script as an argument:
$ ruby -e "while gets; print if /foo/../bar/ end"
I would avoid using $_ as an implicit parameter and instead use something like:
while line = gets
print line if line=~/foo/..line=~/bar/
end
I think Neil Slater is right: It looks like a bug in a parser. If I change the code to
#!/usr/bin/ruby
while gets
print if $_=~/foo/..$_=~/bar/
end
the warning disappears.
I'll file a bug report.

What's the name of "<<-JS" operator [duplicate]

For example:
code = <<-EOH
bundle install
bundle exec unicorn -c /etc/unicorn.cfg -D
EOH
What does this code do? What is <<- called?
It's called heredoc. An easy way to define multiline strings which may include single or double quotes without needing to escape them.
See more here, for example.
Often you use heredocs to define large chunks of code. Some editors know about this and can highlight syntax for you there (if you specify language). Look:
There is also a newer HEREDOC syntax for Ruby <<~END that more closely resembles what you would typically see in most shells and other languages with the ~ instead of the - to tell Ruby to strip the leading whitespace to match the least indented line in the block.
https://infinum.co/the-capsized-eight/multiline-strings-ruby-2-3-0-the-squiggly-heredoc
Looks to me like heredoc. The - allows the ending delimiter to ignore whitespace before it.
A simple Google Search gave me this.

What does "<<-" mean in Ruby?

For example:
code = <<-EOH
bundle install
bundle exec unicorn -c /etc/unicorn.cfg -D
EOH
What does this code do? What is <<- called?
It's called heredoc. An easy way to define multiline strings which may include single or double quotes without needing to escape them.
See more here, for example.
Often you use heredocs to define large chunks of code. Some editors know about this and can highlight syntax for you there (if you specify language). Look:
There is also a newer HEREDOC syntax for Ruby <<~END that more closely resembles what you would typically see in most shells and other languages with the ~ instead of the - to tell Ruby to strip the leading whitespace to match the least indented line in the block.
https://infinum.co/the-capsized-eight/multiline-strings-ruby-2-3-0-the-squiggly-heredoc
Looks to me like heredoc. The - allows the ending delimiter to ignore whitespace before it.
A simple Google Search gave me this.

Resources