Change the context/binding inside a block in ruby Change the context/binding inside a block in ruby ruby ruby

Change the context/binding inside a block in ruby


Paste this code:

  def evaluate(&block)    @self_before_instance_eval = eval "self", block.binding    instance_eval &block  end  def method_missing(method, *args, &block)    @self_before_instance_eval.send method, *args, &block  end

For more information, refer to this really good article here


Maybe

def command(*names, &blk)  command = make_command_object(..)  command.instance_eval(&blk)end

can evaluate the block in the context of command object.


class CommandDSL  def self.call(&blk)    # Create a new CommandDSL instance, and instance_eval the block to it    instance = new    instance.instance_eval(&blk)    # Now return all of the set instance variables as a Hash    instance.instance_variables.inject({}) { |result_hash, instance_variable|      result_hash[instance_variable] = instance.instance_variable_get(instance_variable)      result_hash # Gotta have the block return the result_hash    }  end  def desc(str); @desc = str; end  def switch(sym); @switch = sym; end  def action(&blk); @action = blk; endenddef command(name, &blk)  values_set_within_dsl = CommandDSL.call(&blk)  # INSERT CODE HERE  p name  p values_set_within_dsl endcommand :list do  desc 'show todos in long form'  switch :l  action do |global,option,args|    # some code that's not relevant to this question  endend

Will print:

:list{:@desc=>"show todos in long form", :@switch=>:l, :@action=>#<Proc:0x2392830@C:/Users/Ryguy/Desktop/tesdt.rb:38>}