Skript: "Contains" Doesn't Work When List is Empty

Created on 29 Aug 2018  路  9Comments  路  Source: SkriptLang/Skript

command /s:
    trigger:
        {_s::*} contains "a":
            send "contains"
        {_s::*} doesn't contain "a":
            send "doesnt contain"

{_s::*} is empty. This command send nothing to me. Both "contains" and "doesn't contain" return false it the list is empty.

completed enhancement medium

Most helpful comment

Smart programming with Skript often includes handling false or disabled states by having the variable not exist at all. This isn't possible in many languages but in Skript we have the freedom to say if {_random garbage variable name} is set which saves on both memory and load time. That being the case, my opinion is that unset variables should be respected somewhat like a falsy value because we know that people will be checking values against unset variables as if they were set. So IMO an unset variable should effectively act like a set-but-empty list for all intents and purposes - adding stuff to it works, removing stuff does nothing but doesn't fail/error, and checking contains against it never passes while doesn't contain should always pass.

All 9 comments

What version of Skript are you running?

It occurs on both dev-37c and dev-36.

Can somebody please check whether this happens too for example with %entities% are in world %world% vs %entities% aren't in world %world% or "%livingentities% are wearing %itemtypes% vs "%livingentities% aren't wearing %itemtypes%? If so then the .check method of the SimpleExpression class might require some modification

Isn't this related to how the contains check works?

for (Object o : all) {
    if (Relation.EQUAL.is(Comparators.compare(o, item)))
        return true; // Found equal, success!
}
return false; // Not found

It will return false directly but it will be true because negated.

Before the Checkers:

if (all == null && isNegated())
    return false;

should be enough.

command /a:
  trigger:
    message "start"
    if {_x::*} contains "a":
      message "yes"
    if {_x::*} doesn't contain "a":
      message "no"
    if {_x::*} is in world "world_nether":
      message "yes"
    if {_x::*} isn't in world "world_nether":
      message "no"
    if {_x::*} are wearing iron helmet:
      message "yes"
    if {_x::*} aren't wearing iron helmet:
      message "no"
    message "end"

@Blueyescat my guess was correct, this needs to be reworked in the .check method (unless this behavior is really intended?)

image

This has been reported previously - see #404. It is also intended behavior; variables that do not exist are not lists. It is a bit confusing, though, especially since adding to nothingness creates a list.

Feedback on this welcome. If we decide to change this, it shouldn't be too hard.

Smart programming with Skript often includes handling false or disabled states by having the variable not exist at all. This isn't possible in many languages but in Skript we have the freedom to say if {_random garbage variable name} is set which saves on both memory and load time. That being the case, my opinion is that unset variables should be respected somewhat like a falsy value because we know that people will be checking values against unset variables as if they were set. So IMO an unset variable should effectively act like a set-but-empty list for all intents and purposes - adding stuff to it works, removing stuff does nothing but doesn't fail/error, and checking contains against it never passes while doesn't contain should always pass.

With my recent commit doing for example players in world "world" doesn't contain {_some.online.player} when no players are in the world world should return true, but with list variables the issue (described by @bensku) still exists, and I agree with @TheBentoBox here:

IMO an unset variable should effectively act like a set-but-empty list for all intents and purposes

This is now fixed with the last changes on CondContains.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

cyanide43 picture cyanide43  路  4Comments

Coolfire02 picture Coolfire02  路  3Comments

Misio12320 picture Misio12320  路  3Comments

Eryk1983S picture Eryk1983S  路  3Comments

ghost picture ghost  路  3Comments