deliveredtechnologies / rulebook

100% Java, Lambda Enabled, Lightweight Rules Engine with a Simple and Intuitive DSL
http://www.deliveredtechnologies.com
Apache License 2.0
716 stars 124 forks source link

Why withDefaultResult is mandatory? #187

Open TheDeadOne opened 4 years ago

TheDeadOne commented 4 years ago

It would be convenient to get an empty Optional if no rules were executed.

Clayton7510 commented 3 years ago

withDefault is not mandatory. Having a result was always optional. But if you do have a result and no rules are executed then you would get the default result if you had one.

Do you think it should behave differently?

TheDeadOne commented 3 years ago

Maybe I misunderstood something, but I get an error

cannot find symbol
  symbol:   method addRule(com.deliveredtechnologies.rulebook.model.Rule<com.example.models.SomeClass,java.lang.String>)
  location: class com.deliveredtechnologies.rulebook.lang.RuleBookWithResultTypeBuilder<java.lang.String>

when I try to compile this example without commenting out the line

RuleBook<String> rules = RuleBookBuilder.create()
    .withResultType(String.class)
    //.withDefaultResult("default")
    .addRule(RuleBuilder.create(GoldenRule.class, RuleChainActionType.ERROR_ON_FAILURE)
      .withFactType(SomeClass.class)
      .withResultType(String.class)
      .when(facts -> SomeState.FOO.equals(facts.getOne().getState()))
      .then((facts, result) -> result.setValue("first"))
      .stop()
      .build())
    .addRule(rule -> rule.withFactType(AnotherClass.class)
      .when(facts -> AnotherState.BAR.equals(facts.getValue("another").getState()))
      .then((facts, result) -> result.setValue("second")))
    .build();

NameValueReferableMap<Object> facts = new FactMap<>();
facts.setValue("some", new SomeClass());
facts.setValue("another", new AnotherClass());
rules.run(facts);

I don't need the default. How to get rid of it?

Clayton7510 commented 3 years ago

Ah, so if you have a result, then yes, you need to specify a default value. However, there is no requirement for you to have a result. So, perhaps it was I who misunderstood. But am I correct in understanding now that you want to have a result, but no default result?

Presently, that is not something that's possible without a little trickery, like .withDefaultResult(null) or .withDefaultResult(() -> null), with the latter only supported in the 0.12-SNAPSHOT. But maybe it could be a feature add? I'll tag it as an enhancement request and let's see if we can make that happen.

TheDeadOne commented 3 years ago

Yes, I want to have an empty Optional if no rules executed and no default defined, otherwise Optional of result or a default value if it was defined.