Как делают Вас stringize/serialize код Ruby?

В Java все находится в форме класса.

Если вы хотите использовать любой объект, тогда у вас есть две фазы:

  1. Объявить
  2. Инициализация

Пример:

  • Объявление: Object a;
  • Инициализация: a=new Object();

То же самое для концепции массива

  • Объявление: Item i[]=new Item[5];
  • Инициализация: i[0]=new Item();

Если вы не дают секцию инициализации, тогда возникает NullpointerException.

16
задан 12 revs, 4 users 73% 23 May 2017 в 11:47
поделиться

3 ответа

Ruby2Ruby

def save_for_later(&block)
  return nil unless block_given?

  c = Class.new
  c.class_eval do
    define_method :serializable, &block
  end
  s = Ruby2Ruby.translate(c, :serializable)
  s.sub(/^def \S+\(([^\)]*)\)/, 'lambda { |\1|').sub(/end$/, '}')
end

x = 40
s = save_for_later { |y| x + y }
# => "lambda { |y|\n  (x + y)\n}"
g = eval(s)
# => #<Proc:0x4037bb2c@(eval):1>
g.call(2) 
# => 42

Использования Здорово, но это не закрывается по свободным переменным (как x) и сериализирует их наряду с лямбдой.

К сериализируют переменные также, можно выполнить итерации более чем local_variables и сериализировать их также. Проблема, тем не менее, состоит в том что local_variables из save_for_later доступы только c и s в коде выше - т.е. переменные, локальные для кода сериализации, не вызывающей стороны. Таким образом, к сожалению, мы должны продвинуть захват локальных переменных и их значений вызывающей стороне.

, Возможно, это - хорошая вещь, тем не менее, потому что в целом, нахождение всех свободных переменных в части кода Ruby неразрешимо . Плюс, идеально мы также сохранили бы global_variables и любые загруженные классы и их переопределенные методы. Это кажется непрактичным.

Используя этот простой подход, Вы получаете следующее:

def save_for_later(local_vars, &block)
  return nil unless block_given?

  c = Class.new
  c.class_eval do
    define_method :serializable, &block
  end
  s = Ruby2Ruby.translate(c, :serializable)
  locals = local_vars.map { |var,val| "#{var} = #{val.inspect}; " }.join
  s.sub(/^def \S+\(([^\)]*)\)/, 'lambda { |\1| ' + locals).sub(/end$/, '}')
end

x = 40
s = save_for_later(local_variables.map{ |v| [v,eval(v)] }) { |y| x + y }
# => "lambda { |y| _ = 40; x = 40;\n  (x + y)\n}"

# In a separate run of Ruby, where x is not defined...
g = eval("lambda { |y| _ = 40; x = 40;\n  (x + y)\n}")
# => #<Proc:0xb7cfe9c0@(eval):1>
g.call(2)
# => 42

# Changing x does not affect it.
x = 7
g.call(3)
# => 43
12
ответ дан 30 November 2019 в 22:37
поделиться

Проверьте ответы на этот вопрос .

2
ответ дан 30 November 2019 в 22:37
поделиться

Ruby имеет класс Маршала, который имеет метод дампа, который можно назвать.

Смотрят здесь:

http://rubylearning.com/satishtalim/object_serialization.html

-8
ответ дан 30 November 2019 в 22:37
поделиться
Другие вопросы по тегам:

Похожие вопросы: