LINUX.ORG.RU

Eval Ruby и магия

 


0

2

Дано:

method = "i => Label1.text = i.ToString()"
var = method[/[^ ]*/]
new1 = eval("method.gsub!(/#{var}\\\./, 'auto_var.')")
Всё работает как и задумывалось и на выходе я получаю
i => Label1.text = auto_var.ToString()
Но стоит чуть-чуть изменить строку на входе на
i => Label1.text = i[0].ToString()
то в итоге на выходе переменная new1 становится равной nil. В чём проблема? Аналогичный код на js работает
let v = m.match(/[^ ]/)[0];
let r = eval(`m.replace(/${v}\\\./, 'auto_var.')`);
return eval(`r.replace(/${v}\\\[/, 'auto_var[')`);

Ответ на: комментарий от theNamelessOne

Допустим что есть. В принципе регулярку можно и по другому собирать. Просто хочется понять принципы работы интерпретатора. просто с целью узнать что-то новое.

NextGenenration
() автор топика
Ответ на: комментарий от NextGenenration

У тебя код на Ruby и на Javascript не эквивалентный. gsub! — деструктивный метод, который меняет оригинальную строку и возвращает nil, если замена не произведена, replace же (не деструктивный метод, т.к. возращает новую строку) в таком случае вернёт оригинальную строку; такого поведения в Ruby можно добиться с помощью метода gsub. Плюс у тебя в Javascript выполняется две замены в отличие от одной в Ruby.

def dummy_replace(code, replacement, continuations: ['.', '['])
  var = code[/^\s*([^ ]+) /, 1]
  pattern = /\b#{Regexp.escape(var)}(#{Regexp.union(continuations)})/
  code.gsub(pattern, "#{replacement}\\1")
end

puts
puts 'Works out of the box!'
puts dummy_replace('i => Label1.text = i.ToString()', 'auto_var')
puts dummy_replace('i => Label1.text = i[0].ToString()', 'auto_var')

puts
puts "Doesn't work :'("
puts dummy_replace('i => Label1.text = i(2, 3)', 'auto_var')

puts
puts 'But this one does!'
puts dummy_replace('i => Label1.text = i(2, 3)', 'auto_var', continuations: '(')

Результат:

Works out of the box!
i => Label1.text = auto_var.ToString()
i => Label1.text = auto_var[0].ToString()

Doesn't work :'(
i => Label1.text = i(2, 3)

But this one does!
i => Label1.text = auto_var(2, 3)
theNamelessOne 👍
()
Последнее исправление: theNamelessOne (всего исправлений: 1)
method = "i => Label1.text = i.ToString()"
var = method[/[^ ]*/]
new1 = eval("method.gsub!(/#{var}([\\[|\\.])+/, 'auto_var\\1')")

puts new1

Работает для

i => Label1.text = i.ToString()
и
i => Label1.text = i[0].ToString()

Sorcus
()
Ответ на: комментарий от Sorcus

Плюс лишний.

/#{var}([\\[|\\.])/
Вот так лучше.

P.S. Почему нельзя редактировать сообщения? Ппц как неудобно :-/ И инфы не нашел по редактированию...

Sorcus
()
Ответ на: комментарий от theNamelessOne

да тут сразу видно диагноз, чувакк «пруфы» сделал и топик создал, а сам в одной строчке кода запутался

anonymous
()

Сейчас бы код строками генерировать в 2017

loz
()
Ответ на: комментарий от theNamelessOne

Плюс у тебя в Javascript выполняется две замены в отличие от одной в Ruby.

На самом деле я привёл не весь код на руби. В данный момент код целиком имеет следующий вид

code = "if(Class.Method(arg).With(i => Label1.text = i[0].ToString()) == 0) {
	Stop();
}"

index = code.index("With")

b1 = 0 # []
b2 = 0 # {}
b3 = 0 # ()

start = index - 1

while b1 > -1 and b2 > -1 and b3 > -1
	start -= 1
	if code[start] == "("
		b3 -= 1
	elsif code[start] == ")"
		b3 += 1
	elsif code[start] == "["
		b1 -= 1
	elsif code[start] == "]"
		b1 += 1
	elsif code[start] == "{"
		b2 -= 1
	elsif code[start] == "}"
		b2 += 1
	end
end

start +=1

print(code[start..index - 2])

body_end = index
b3 = 0
load = true

while b3 != 0 or load
	body_end += 1
	if code[body_end] == "("
		b3 -= 1
		load = false
	elsif code[body_end] == ")"
		b3 += 1
	end
end
method = code[index + 5..body_end - 1]
var = method[/[^ ]*/]
new1 = eval("method.gsub(/#{var}\\\./, 'auto_var.')")
new2 = eval("new1.gsub(/#{var}\\\[/, 'auto_var[')")

print(new2)
Разрабатываю данный велосипед с целью проверить идею о том насколько можно автоматизировать изменение кода на c#. по началу думал создать плагин для студии, но пока смотрел на объём кода на c++ автоматически сгенерированного при создании проекта желание отпало.

NextGenenration
() автор топика
Ответ на: комментарий от theNamelessOne

Тут парсер нужен.

может плохо искал, но привязок к ruby|js не нашёл. надо будет посмотреть как это дело выглядит на самом c#. Хотя это должно быть лишь полуавтоматическим процессом и я допускаю то что возможно в некоторых местах надо будет доредактировать руками. при текущих требованиях проще будет десяток костылей прикрутить чем реализовывать по стандартам. Возможно позже поделюсь наработками.

NextGenenration
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.