Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Concatenate procs while retaining context reevaluation capabilities

I want to concatenate the bodies of two procs. But unlike here, there is a twist. The resulting proc should retain the original procs' instance_eval-ability.

It might sound a little confusing, so here is my use case.


I'm implementing another language as internal DSL in Ruby. An oversimplified implementation:

class Interpreter
  def self.run(&program)
    Interpreter.new.instance_eval(&program)
  end

  def initialize
    @variables = {}
  end

  def assign_variable(name, value)
    @variables[name] = value
  end

  def display(name)
    puts @variables[name]
  end
end

Interpreter.run do
  assign_variable :foo, 42
  display :foo
end

If I split the body of the proc into two other:

assignment = proc { assign_variable :foo, 42 }
printing   = proc { display :foo }
combined   = proc { assignment.call; printing.call }

Interpreter.run(&combined)

It wont work because the combined proc is being instance_eval-ed, but the assignment and printing procs are evaluated in the context of the place they were defined.

The reason I want to split the original proc is so that I can DRY my tests.

like image 912
ndnenkov Avatar asked Oct 29 '25 14:10

ndnenkov


1 Answers

You can do

combined = proc {
  instance_eval &assignment
  instance_eval &printing
}

But I wouldn't be surprised if someone comes up with something more idiomatic

like image 177
Damiano Stoffie Avatar answered Oct 31 '25 11:10

Damiano Stoffie