Eval operator in Salesforce or Eval is not Evil

Is Eval Evil or not? Despite many authors try to convince us that Eval is evil, I would personally disagree. I believe Eval operator in Javascript is a great and sophisticated tool for sophisticated and responsible developers. I believe you have probably seen that picture which claims that with Great Beard Comes Great Responsibility.

great-beard-400x400-1

So Eval operator is not evil or good, it is just a tool without any ethical color like a scalpel in the hands of the surgeon. Definitely you should use it in a right way. Information for linguists: “Eval” is just shortened form of “evaluate” verb, developers are generally lazy and tend to shorten everything which is possible to shorten, especially they like to shorten words, so they always use some brief combination of letters to save time.

There were several discussions about existence of functionality in Salesforce Apex language which would allow developers to execute code like JavaScript Eval operator ([1], [2]).
Obviously there is no Eval operator in Apex. However, some people have invented some options to mimic a Javascript eval() in Apex (in the links above).
So, the first option was to use ToolingAPI library’s executeAnonymousUnencoded method and throw some custom exception and catch it to receive the result, approach described here and here. The second link looks like the same as the site from the first link. Probably it has been moved from WordPress blog to separate domain. This approach is followed by this code sample

public class Dynamic {
    public class IntentionalException extends Exception{}
 
    public static boolean eval(String toEval){
        boolean result = false;
        if(!toEval.startsWith('if')) {
            toEval = 'if(' + toEval + ') {throw new Dynamic.IntentionalException(\'true\');} else {throw new Dynamic.IntentionalException(\'false\');}';
        }
        ToolingAPI x = new ToolingAPI();
        try{
            ToolingAPI.ExecuteAnonymousResult toolingResult = x.executeAnonymousUnencoded(toEval);
        } catch (IntentionalException ie) {
            result = (ie.getMessage() == 'true') ? True : False;
        }
        return result;
    }
}

Another approach invented by Daniel Ballinger is to parse apex debug logs to retrieve results. To use this approach you don’t need ToolingAPI library but you require his wrapper class. Having it you may run one of his examples.

To evaluate concatenation of strings you may use following example:

string output = soapSforceCom200608Apex.evalString('string first = \'foo\'; string second = \'bar\'; string result = first + second; System.debug(LoggingLevel.Error, result);');  
System.assertEquals('foobar', output);  
System.debug(LoggingLevel.ERROR, ' output= '+ output);

To evaluate sum of integers you may use following example:

integer output = soapSforceCom200608Apex.evalInteger('integer first = 1; integer second = 5; integer result = first + second; System.debug(LoggingLevel.Error, result);');  
System.assertEquals(6, output);  
System.debug(LoggingLevel.ERROR, ' output= '+ output);  

To evaluate logical disjunction of boolean values you may use following example:

boolean output = soapSforceCom200608Apex.evalBoolean('boolean first = true; boolean second = false; boolean result = first || second; System.debug(LoggingLevel.Error, result);');  
System.assertEquals(true, output);  
System.debug(LoggingLevel.ERROR, ' output= '+ output);

To evaluate JSON serialization of object you may use following example:

string outputJson = soapSforceCom200608Apex.evalString('List<object> result = new List<object>(); result.add(\'foo\'); result.add(12345); System.debug(LoggingLevel.Error, JSON.serialize(result));');  
System.debug(LoggingLevel.ERROR, ' outputJson= '+ outputJson);
List<Object> result =   
   (List<Object>)JSON.deserializeUntyped(outputJson);  
System.assertEquals(2, result.size());  
System.assertEquals('foo', result[0]);  
System.assertEquals(12345, result[1]);

To run examples using any approach described above you need Author Apex permission (included in standard System Administrator profile), access to tooling API or SOAP API (basically if you are administrator you should have this access) and you need to add URL of your own organization to Remote Site settings. You may found your URL in browser address bar or by running anonymous apex code

System.debug( LoggingLevel.ERROR, ' url= '+ ( URL.getSalesforceBaseUrl().toExternalForm()  + '/services/Soap/s/31.0' ) );

I was very impressed when I discovered that there is a possibility to mimic a Javascript eval operator in Apex. Hope you too. Eval is definitely not a root of all evil. Enjoy. 🙂

This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s