Any way to check the existence of a variable?

The place to post your WML questions and answers.

Moderator: Forum Moderators

Forum rules
  • Please use [code] BBCode tags in your posts for embedding WML snippets.
  • To keep your code readable so that others can easily help you, make sure to indent it following our conventions.
Post Reply
User avatar
WhiteWolf
Forum Moderator
Posts: 769
Joined: September 22nd, 2009, 7:48 pm
Location: Hungary

Any way to check the existence of a variable?

Post by WhiteWolf »

Hi,

Is there any way to check if a variable has been created? Let's call it $var, and the logical test should yield true if there is a variable with name=var in the memory (regardless of its content), and yield false, if no such variable has been created yet.
Long story:
So far, I can't find anything that would make this possible. contains="" doesn't work, it even fires if the variable doesn't exist. boolean_equals="" doesn't work, it fires if the variable doesn't exist, but also fires if the variable equals a 'no' as a boolean.

Any ideas? Or just declare that the new version is simply incompatible with the earlier ones, so everyone who updated must...restart the whole campaign?
Main UMC campaigns: The Ravagers - now for 1.16, with new bugs!
Old UMC works: The Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
User avatar
zookeeper
WML Wizard
Posts: 9742
Joined: September 11th, 2004, 10:40 pm
Location: Finland

Re: Any way to check the existence of a variable?

Post by zookeeper »

The most common way seems to be to compare it to a non-existent variable, so for example equals=$empty would yield true if the given variable doesn't exist (and, of course, assuming that $empty doesn't exist either).
User avatar
WhiteWolf
Forum Moderator
Posts: 769
Joined: September 22nd, 2009, 7:48 pm
Location: Hungary

Re: Any way to check the existence of a variable?

Post by WhiteWolf »

This seems to work fine, thanks :)
Main UMC campaigns: The Ravagers - now for 1.16, with new bugs!
Old UMC works: The Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: Any way to check the existence of a variable?

Post by Sapient »

In WML, an empty scalar variable is equivalent to an undefined scalar variable.
In Lua, I believe you can check for wesnoth.get_variable("my_variable")==nil
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
Shiki
Developer
Posts: 348
Joined: July 13th, 2015, 9:53 pm
Location: Germany

Re: Any way to check the existence of a variable?

Post by Shiki »

This sounds interesting.
In my case, I'm using two variables currently, one for checking If an previsouls event occured, and a second to unstore a unit which I will only have then. Basically, I'm testing if I have the 2nd Variable.

Code: Select all

        [if]
            [variable]
                name=WillEvent
                equals=1
            [/variable]
            [then]
                [unstore_unit]
                    variable=WillV
                    x,y=5,35
                [/unstore_unit]
                {CLEAR_VARIABLE WillV}
                 ... ... (lots of other WML stuff based on that [if], like dialogs and another [event] tag )
            [/then]
        [/if]
        {CLEAR_VARIABLE WillEvent}
Can I use the lua function with a [lua] tag shoehow as the conditional for the [if] ?
I suppose not (?), but maybe doing the [if] part in lua too, but still having the part after [unstore_unit] in WML?
The idea of refactoring away one variable looks for me now like rocket science...

Edit: So I tried zookeepers advice, and it doesn't look at all that hacky I thought.
But there is one trap. Comparing the array variable WillV with a nonexistent will everytime return true, no matter if it exists or not. You have to compare sth. like WillV.id with the nonexistent variable.
Try out the dark board theme.
enclave
Posts: 936
Joined: December 15th, 2007, 8:52 am

Re: Any way to check the existence of a variable?

Post by enclave »

I'm not sure if I'm posting something related to your problem... or if somebody already gave you same answer (I couldn't understand if zookeeper's equals=$empty is the same thing or not.. so I thought I would add something)

Wiki says:
Boolean Values

When values are evaluated as boolean values they are checked to see if they are false or true.

These values are evaluated as true: "yes" and "true"
These values are evaluated as false: "no", "false" and ""(uninitialized)
However, in contexts where true is defined as the default value, an uninitialized value would be considered true.

Warning: Do not use "off", "on", integers, floating-point numbers or anything else than the above as booleans.
So from that I could only understand that if the value is uninitialized (empty/non-existant) it will return false in the check:

Code: Select all

[if]
    [variable]
        name=some_variable
        boolean_equals=false
    [/variable]
    [then]
        ## variable is empty
    [/then]
    [else]
        ## variable is not empty.. and possibly equals true?
    [/else]
[/if]
But I must mention that I think I tried it and it didn't work or it was some other issue in my code.. so I can not confirm that it really works, I don't remember. If you like alternative ways.. try this example.. and let us know.. Thanks..
User avatar
WhiteWolf
Forum Moderator
Posts: 769
Joined: September 22nd, 2009, 7:48 pm
Location: Hungary

Re: Any way to check the existence of a variable?

Post by WhiteWolf »

No, this surely won't work. Let's say var equals false. {VARIABLE var false}. Then this type of logical test would trigger if the variable is uninitialized, but also triggers if var=false. This is not what we want.

Code: Select all


[if]
  [variable]
    name=var
    boolean_equals=false
  [/variable]
  [then]

  # it yields true all right

  [/then]
[/if]

# rest of code
{VARIABLE var false}
[if]
  [variable]
     name=var
     boolean_equals=false
  [/variable]
  [then]

  # it yields true, but var is initialized! It no longer works as wanted.

  [/then]
[/if]


Currently, only zookeeper's equals=$empy_nonexistnt is the solution that works best, in my experience.
Main UMC campaigns: The Ravagers - now for 1.16, with new bugs!
Old UMC works: The Underness Series, consisting of 5 parts: The Desolation of Karlag, The Blind Sentinel, The Stone of the North, The Invasion Of The Western Cavalry, Fingerbone of Destiny
User avatar
The_Gnat
Posts: 2217
Joined: October 10th, 2016, 3:06 am
Contact:

Re: Any way to check the existence of a variable?

Post by The_Gnat »

Hmm... not sure this is what you are looking for but i always use words for my variables (rather than boolean) that way when it equals "no" it is not because it is empty.

Code: Select all

    {VARIABLE var no}
    [if]
      [variable]
         name=var
         equals=no
      [/variable]
      [then]

      [/then]
    [/if]
This way the if statement will not run if there is no variable.

(hopefully this helps :D )
enclave
Posts: 936
Joined: December 15th, 2007, 8:52 am

Re: Any way to check the existence of a variable?

Post by enclave »

or I assume you could convert it into lua and test it there.. but it's not WML workshop anymore..
not sure if it works either, but it would be something like this:
for example you need to test if variable "doll_house" exists..

Code: Select all

[lua]
code = <<
if wesnoth.get_variable("doll_house") then wesnoth.set_variable("nil_test_variable","exists") end
>>
[/lua]
[if]
    [variable]
        name=nil_test_variable
        equals=exists
    [/variable]
    [then]
        ## then your variable exists..
    [/then]
[/if]
not 100% sure if I wrote the lua if then correctly, maybe it needs to look like this:
if wesnoth.get_variable("doll_house")==nil then wesnoth.set_variable("nil_test_variable","exists") end
I'm quite new to lua.. and prefer not to use it unless there is really no other way.
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: Any way to check the existence of a variable?

Post by Sapient »

A few points re:enclave's post.

1. Your second form was correct, not the first form. However I already stated that information (check my previous post in this thread).
2. Since you are only setting nil_test_variable conditionally, the value could be wrong after multiple uses.
3. The original poster of this question has already clarified that they don't really need to distinguish between empty and uninitialized variables, since they only care if the variable is effectively empty, i.e. equals=$empty
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
User avatar
Pentarctagon
Project Manager
Posts: 5564
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Any way to check the existence of a variable?

Post by Pentarctagon »

In 1.13.2+, you can also use the new syntax:

Code: Select all

$varname?default_value|
As a macro:

Code: Select all

#define DEFAULT VAR VAL

{VARIABLE {VAR} ${VAR}?{VAL}|}

#enddef
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
Sapient
Inactive Developer
Posts: 4453
Joined: November 26th, 2005, 7:41 am
Contact:

Re: Any way to check the existence of a variable?

Post by Sapient »

Pentarctagon wrote:In 1.13.2+, you can also use the new syntax:

Code: Select all

$varname?default_value|
I tried to lookup the documentation for that feature, but I couldn't find it on the SyntaxWML page.

So does it have the same effect for empty string ("") variables or does it only supply a default for uninitialized (i.e. Lua nil) variables?
http://www.wesnoth.org/wiki/User:Sapient... "Looks like your skills saved us again. Uh, well at least, they saved Soarin's apple pie."
Post Reply