Строковые операции и `eval` - PullRequest
1 голос
/ 22 марта 2019

У меня есть лямбда-функция AWS, которая получает код пользователя из браузера в виде строки и запускает eval в изолированной среде, как в стандартном REPL. Я не пытаюсь интерполировать строку. Я пытаюсь eval распознать и выполнить операции со строками.

Я несколько ограничен в операциях, которые могу выполнять. Основная замена регулярных выражений - это круто, но я не думаю, что смогу сделать что-то более сложное, но, возможно, я ошибаюсь.

Это работает для основных арифметических операций, создания экземпляров классов и т. Д. Однако он не может правильно выполнять строковые операции. Когда я прохожу:

eval `("3*4")`

возвращает 12, и это здорово. Однако, если я пройду:

eval(""str:" + " test"")

Не удается вернуть "str: test". На самом деле это ничего не возвращает.

Было предложено избежать двойных кавычек. В REPL работает замена всех двойных кавычек на экранированные, такие как \".

eval("\"str \" + \"test\"") # => "str test"

Однако, когда я пытаюсь сделать это с AWS, он возвращает "\"str \" + \"test\"".

Я с нетерпением жду ваших ответов.

Ответы [ 3 ]

1 голос
/ 22 марта 2019

Кажется, я нашел обходной путь.

Для начала я сначала выясню, в чем заключалась моя проблема.Скажем, пользователь ввел следующее:

class Test
   attr_accesssor :data
   def initialize(data = nil)
      @data = data
   end
end

, за которым следует

Test.new(4).data

eval, вернёт верное значение 4.

Теперь скажите, однако, что пользователь вместо этогонаписал

Test.new("A nice, fine string").data

eval ничего бы не вернул.

Однако я заметил, что если бы я нажал на .inspect, как показано ниже:

Test.new("A nice, fine string").data.inspect

Мне бы вернули A nice, fine string.

Поэтому мое решение заключалось в том, чтобы заключить весь код пользователя в круглые скобки, а затем вызвать .inspect.

выполнено по следующей строке

code = "(" << code << ").inspect"

Спасибо всем, кто нашел время, чтобы помочь мне.Я действительно ценю все отзывы и предложения.

1 голос
/ 22 марта 2019

Вы не должны ожидать, что eval(""str:" + " test"") будет работать.Проблема не связана с AWS лямбда.Если вы попробуете это на своей машине, используя pry или irb, вы получите SyntaxError.Это потому, что ваш интерпретатор не может понять, что вы передаете eval только одну объединенную строку.Поэтому вам нужно экранировать все кавычки внутри вашей строки:

eval("\"str \" + \"test\"")

Если вы проверили его в REPL без экранирования, и это сработало, то кажется, что используемый вами REPL каким-то образом изменяет ваш ввод передотправив его переводчику.

0 голосов
/ 22 марта 2019

Вы должны быть осторожны с интерполяцией строк при использовании eval для строк:

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\""

однако это вызовет ошибки

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

, но это будет работать

eval("puts #{str.inspect}")
#=> This is my String. It's name is string. Now I can eval "Hooray for my string"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...