2

Is there a way in apex that I can use a dynamic expression operators. For eg.

var operator = '>';

if( a operator b) {

}else{

}

6

Not directly; Apex Code is a strongly typed language, and doesn't really have the capacity to evaluate code in an interpreted manner. The closest you'd probably get is either rigging your own interface, or using Visualforce expression evaluation, which is fraught with limitations and pitfalls.

For example, let's say you built this interface:

interface BinaryOperator {
    Object evaluate(Object a, Object b);
}

You could then implement classes:

class StringLessThanBinaryOperator implements BinaryOperator {
    public Object evaluate(Object a, Object b) {
        return (String)a < (String)b;
    }
}

Which you could then call using the interface:

BinaryOperator op = new StringLessThanBinaryOperator();
String a = 'Hello', b = 'World';
if((Boolean)op.evaluate(a, b)) {
    // ... A is less than B

We also don't have template interfaces, so this means you'd also be forced to implement types for each data type you want to support. However, some standard types can be evaluated using the Comparable interface, which means that you could get some built-in support for less-than, less-or-equal, equal, greater-than, and greater-or-equal by calling, for example:

if(a.compareTo(b)<0) { // A is strictly less than B

if(a.compareTo(b)==0) { // A is equal to B

As far as the Visualforce expression method, you can write code like this:

Component.Apex.OutputText text = new Component.Apex.OutputText();
text.expressions.value = '{!IF(A < B, A, B)}';
String result = text.value;

However, as far as I know, variables you examine in this manner have to conform to Visualforce rules, like having a public getter/setter, etc. Therefore, it's also incredibly limited, but you can construct strings that could be used to determine values dynamically.

4

If you want to do a lot of that sort of logic you can factor it out into a separate class:

String operator = '>';
if (Ops.create(operator).evaluate(a, b)) {
    ...
} else {
    ...
}

So Ops.create is a static factory method that creates instances of the sort of interface that sfdcfox describes.

0

I don't think this is possible. I have seen similar where you create the logic in code e.g.

    if(operator == '>' && a > b){
    }else{
    }
    if(operator == '<' && a < b){
    } else{
    }
0

You can use ExecuteAnonymousResult executeAnonymous(String code) for something like you describe, but it would need to contain the complete string. As such, you'd need to modify the complete string of code when you wanted to change the operator. There are a number of limitations on this and it's not especially well documented on exactly how to use it. See Anonymous Blocks, SOAP API and SOAP Headers for Apex from the Apex Developer's User Guide.

From the documentation:

An anonymous block is Apex code that does not get stored in the metadata, but that can be compiled and executed using one of the following:

  • Developer Console
  • Force.com IDE
  • The executeAnonymous() SOAP API call:

From the above, since it's not stored in the metadata, I don't believe it could be included in say a trigger or a class. Here's more from the documentation:

You can use anonymous blocks to quickly evaluate Apex on the fly, such as in the Developer Console or the Force.com IDE, or to write code that changes dynamically at runtime. For example, you might write a client Web application that takes input from a user, such as a name and address, and then uses an anonymous block of Apex to insert a contact with that name and address into the database.

Note the following about the content of an anonymous block (for executeAnonymous(), the code String):

  • Can include user-defined methods and exceptions.
  • User-defined methods cannot include the keyword static.
  • You do not have to manually commit any database changes.
  • If your Apex trigger completes successfully, any database changes are automatically committed. If your Apex trigger does not complete successfully, any changes made to the database are rolled back.
  • Unlike classes and triggers, anonymous blocks execute as the current user and can fail to compile if the code violates the user's object- and field-level permissions.
  • Do not have a scope other than local. For example, though it is legal to use the global access modifier, it has no meaning. The scope of the method is limited to the anonymous block.
  • When you define a class or interface (a custom type) in an anonymous block, the class or interface is considered virtual by default when the anonymous block executes. This is true even if your custom type wasn’t defined with the virtual modifier. Save your class or interface in Salesforce to avoid this from happening. Note that classes and interfaces defined in an anonymous block aren’t saved in your organization.

I'm not certain if this code could be called from say a custom object to run in production code as it can't be included in the metadata. So how to use it other than in Execute Anonymous, etc could be problematic.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.