April 29, 2015

Is Eval Evil or not?

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

More Value with Lightning Value Providers

February 15, 2019 | Bohdan Dovhan, Senior Salesforce Engineer

Salesforce cloud platform offers the whole variety of customization options. Those include point-and-click tools like Lightning App Builder, Process Builder, Visual Flow and Workflow alongside development tools like Apex, Visualforce, Lightning Aura Components, Lightning Aura Events, Lightning Aura Tokens, Lightning Aura Standalone application and Lightning Web Components. Lightning Aura Components development involves the development of […]

Hot in Salesforce Marketing Cloud: January 2019 Release Notes

February 8, 2019 | Ihor Shupeniuk, Salesforce Engineer and Marketing Cloud Specialist

In the era of intelligent marketing with the proliferation of technology where modern consumers are offered the widest choice, Marketing Cloud is sometimes named a future-looking service, We continue to closely follow the developments and improvements to  Marketing Cloud and we can safely affirm that this product is becoming better and better. Everyone who has […]