Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
instance_eval without changing self
Ruby
branch: master

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
lib
test
.yardopts
CHANGELOG
README.markdown
Rakefile

README.markdown

LocalEval

(C) John Mair (banisterfiend) 2010

instance_eval without changing self

Using local_eval you get most of the benefits of instance_eval with very few of the drawbacks: local instance variables are accessible within the block and method lookups are directed to the correct receiver. Unlike instance_eval the self of the block is not changed.

LocalEval provides the local_eval and local_eval_with methods.

example: local_eval

Using local_eval we can add the functionality of the receiver to the block:

class C
  def hello(name)
    "hello #{name}!"
  end
end

o = C.new

@name = "John"
o.local_eval { hello(@name) } #=> "hello John!"

example: capture

Since local_eval does not alter the self inside a block, all methods with an implied receiver will be invoked with respect to this local self. This means that all mutator methods defined on the receiver will modify state on the block's self rather than on the receiver's self. This is unlikely to be the desired behaviour; and so we can use the capture method to redirect method lookup to the actual receiver. All code captured by the capture block will be instance_eval'd against the actual receiver of the method.

class C
  class << self
    attr_reader :hello
    def self.capture_test

      # this code will be run against C
      capture { @hello = :captured }

      # this code will be run against the block context
      @goodbye = :goobye
    end
  end
end

C.local_eval { capture_test }

C.hello #=> :captured
@goodbye #=> :goodbye

How it works

Makes use of companion libraries: Remix and Object2module

Thread Safety

local_eval is not threadsafe.

Companion Libraries

LocalEval is one of a series of experimental libraries that mess with the internals of Ruby to bring new and interesting functionality to the language, see also:

  • Remix - Makes ancestor chains read/write
  • Object2module - Enables you to include/extend Object/Classes.
  • Include Complete - Brings in module singleton classes during an include. No more ugly ClassMethods and included() hook hacks.
  • Prepend - Prepends modules in front of a class; so method lookup starts with the module
  • GenEval - A strange new breed of instance_eval

Contact

Problems or questions contact me at github

Something went wrong with that request. Please try again.