Is Eval Evil or not?

April 29, 2015

Though 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.

unnamed
So Eval operator is not evil or good, it is just a tool without any ethical color like a scalpel in hands of a surgeon. Definitely you should use it in the right way. Information for linguists: “Eval” is just a shortened form of an “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 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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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 the following example:

1
2
3
4
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 the following example:

1
2
3
4
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 the following example:

1
2
3
4
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 the following example:

1
2
3
4
5
6
7
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 an administrator you should have this access) and you need to add URL of your own organization to Remote Site settings. You may find your URL in browser address bar or by running anonymous apex code

1
2
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. 🙂

Tags



Share


Recent Articles

Get 100% Code Coverage for Salesforce Custom Metadata Based Decisions

January 18, 2018 | Bohdan Dovhan

How to obtain a full coverage for code which uses Custom Metadata for strategy-like decision implementation? Introduction Many applications use configuration data. Configuration data might be relevant to the entire organization, or a subset of user, or even different for each user. For the purposes of this article, we will focus only on global configuration […]

Logging of Exceptions in Salesforce

January 11, 2018 | Mykola Senyk

Unpredicted behaviour in a custom code. Can we eliminate it? The ability to customize your Salesforce org code is not just a “nice to have.”  It greatly increases the capability and flexibility of Salesforce. However, custom code can also be tricky to use. It would be great if we could detect unpredicted behavior in our […]

© Copyright - CoreValue 2018
Salesforce, Sales Cloud, and others are trademarks of salesforce.com, inc., and are used here with permission.
Used with permission from Microsoft.