> On 14 Mar 2017, at 11:23, Raffaello Giulietti 
> <raffaello.giulie...@lifeware.ch> wrote:
> 
> Hi,
> 
> I'm wondering how to programmatically compile a method. I tried using a 
> variant of
>    ClassDescription>>compile:*:notifying:

Yes, this is the Smalltalk API.

You can use the compiler directly and then install the method yourself, too.

The compiler has a number of setters and then a build method (#compile if you 
are interested in a compiled method).

OpalCompiler new
        class: Object;
        source: ‘foo ^1’;
        compile.

or, if you compile for a class the class can give a pre-setup compiler:

Object compiler
        source: 'foo ^1';
        compile.

then you can install the method with addSelector:withMethod: 

> However, on a method with undeclared variables, when the Transcript is open 
> there seems to be no way to avoid a message being written there. Further, the 
> requestor passed as a notifier in the above method is not even notified when 
> the compilation context is not interactive.
> 
Yes, this is sadly right now hard-coded… but in the Exception.

So you can do what the exception does yourself:


method := [Object compiler
        source: 'foo ^a';
        compile] on: OCUndeclaredVariableWarning do: [ :ex | 
           | varName |
                varName := (ex instVarNamed: #node) name.
                Undeclared at: varName asSymbol put: nil.
                ex resume: (OCUndeclaredVariable new name: varName asSymbol). ].


> What is the correct way to use the compiler programmatically and in a non 
> interactive batch, still being able to catch all the compilation errors and 
> warnings?

What we need for the future is to have not just logging but real compiler error 
objects… there are other cases where it would be nice (e.g. to get a list of 
all errors
after loading a package with monticello).

We should improve the compiler for Pharo7… 

        Marcus

Reply via email to