# Module#class\_eval

**URL:** <https://www.ruby-forum.com/t/module-class-eval/125990>\
**Category:** IronRuby\
**Created:** [January 14, 2008, 2:39pm UTC](https://www.ruby-forum.com/t/module-class-eval/125990 "2008-01-14T14:39:33Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![editkid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/977dab/32.png) [@editkid](https://www.ruby-forum.com/u/editkid)\
**Post date:** [January 14, 2008, 2:39pm UTC](https://www.ruby-forum.com/t/module-class-eval/125990/1 "2008-01-14T14:39:33Z")

</div>

I have been playing around with implementing Module#class\_eval, partly  
because I wanted to use it in a test case and partly because I thought  
it  
would help my understanding of the guts of IronRuby. I managed to get  
the  
following code to work but it is not pretty.

```
    [RubyMethod("class_eval")]

    public static object Evaluate(CodeContext/*!*/ context,

```

RubyModule/_!_/ module, MutableString code) {

```
        // Create a new context for running the code string - not 

```

sure  
if this is necessary.

```
        CodeContext context2 = new CodeContext(context);

        // We need a localscope for GetRfc.

        RubyScope localScope = RubyUtils.GetScope(context);

        // Create a local scope for this module definition.

        // (This has a side-effect that context2 has the new module

```

scope attached in its LocalScope property.)

```
        RubyScope moduleScope = RubyOps.CreateModuleScope(context2,

```

localScope.RuntimeFlowControl, module);

```
        // Compile up the code in the new context

        SourceUnit sourceUnit =

```

context2.LanguageContext.CreateSnippet(code);

```
        ScriptCode scriptCode =

```

sourceUnit.Compile(context2.LanguageContext.GetModuleCompilerOptions(context  
2.Scope), null);

```
        // Run the code in the new context.

        // (This overload is currently private but we need to be 

```

able to  
pass in the new context).

```
        return scriptCode.Run(context2, false);

    }

```

I added superfluous comments for the benefit of posting it her. The  
main  
issue, as noted at the bottom of the code, is that the overload of  
ScriptCode.Run that is called is currently private. All the public  
overloads create a new CodeContext and you lose the LocalScope which is  
needed to ensure that the code is run in the context of the module being  
defined.

Any comments on this? I assume that as the Hosting spec evolves this  
could  
get a lot cleaner. Is there a better way right now to achieve the same  
result?

Also, one thing that really messed my head up for quite a while is the  
use  
of the word scope. It took me a while to come to terms with the fact  
that  
there are numerous completely separate scopes: Scope, ScopeExtension  
(which  
contains a Scope property), ScriptScope (which implements IScriptScope)  
and  
RubyScope (which derives from LocalScope).

Am I right in saying:

Scope is the global scope in which the current Ruby program is running  
(with  
ScopeExtension just wrapping that and ScriptScope being a container for  
code  
being run within that scope)?

RubyScope is the local scope within a Ruby program that tells you things  
like what the current self object is and what variables are accessible?

Regards,

Pete

> **[Ironing-Ruby](http://ironingruby.blogspot.com)**
>
> Ramblings from my interactions with IronRuby, the Microsoft .NET implementation of the programming language Ruby.

---

<div class="post-metadata">

**Author:** ![editkid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/977dab/32.png) [@editkid](https://www.ruby-forum.com/u/editkid)\
**Post date:** [January 19, 2008, 12:38am UTC](https://www.ruby-forum.com/t/module-class-eval/125990/2 "2008-01-19T00:38:26Z")

</div>

Peter Bacon D.:

> sure if this is necessary.
> 
> able to pass in the new context).
> 
> Any comments on this? I assume that as the Hosting spec evolves this  
> could get a lot cleaner. Is there a better way right now to achieve  
> the same result?

Nice that you got that working!

I think the main issue you’re running into is that hosting APIs are in  
flux. That’s been a delaying factor on getting all the string-based  
“evals” working. Also, there might be some more work in the compiler  
too; e.g. are we burning in references where we should be looking them  
up dynamically, etc. There might be other things that Tomas has in mind  
that need to be changed. Anyway, I think it makes sense for us to do all  
the eval-related stuff in one push.

> container for code being run within that scope)?
> 
> RubyScope is the local scope within a Ruby program that tells you  
> things like what the current self object is and what variables are  
> accessible?

I think that’s correct. Scope is the DLR global scope thing, while  
ScriptScope is the hosting API version. RubyScope will probably end up  
roughly equivalent to a binding (but it doesn’t have all the stuff  
yet–e.g. locals)

- John

---

<div class="post-metadata">

**Author:** ![editkid](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/977dab/32.png) [@editkid](https://www.ruby-forum.com/u/editkid)\
**Post date:** [January 19, 2008, 1:07am UTC](https://www.ruby-forum.com/t/module-class-eval/125990/3 "2008-01-19T01:07:09Z")

</div>

Well, evals are actually not blocked by hosting API (rather the opposite  
is true for Ruby hosting in console). There is some other stuff that  
needs to be done in DLR and also in Ruby compiler to make eval happen.  
I’m on it, but it will take some time.

Tomas
