This is a question about Template Toolkit for perl.

I render my templates with a little command-line utility that has the following option enabled

```
   DEBUG => Template::Constants::DEBUG_UNDEF,

```

The syntax is `render <file.tt> var1 val1 var2 val2 ....`
This is very convenient because the user gets prompts about values that need to be defined, for example

```
$ render file.tt
undef error - var1 is undefined

$ render file.tt var1 foo 
undef error - var2 is undefined

$ render file.tt var1 foo var2 bar
... template renders correctly

```

For some (optional) values, templates provide defaults, for example:

```
[%- DEFAULT
    hostname = 0
%]

```

Then the template body would typically contain:

```
  [% IF hostname %] hostname = [% hostname %][% ELSE %][% -- a comment, variable hostname not provided %][% END %]

```

How do I make the above idiom work for variables where `0` is a valid value?

I want the following to happen:

```
render template.tt

```

Template renders:

```
  -- this is a comment, variable enable_networking not provided

```

For 

```
  render template.tt enable_networking 0

```

I want

```
  enable_networking = 0

```

The problem is differentiating between defined values and false values. I have tried using `-1` (instead of `0`) both in the `DEFAULT` block and in the `[% IF enable_networking == -1 %]` statement.

However, the following `DEFAULT` block

```
[% DEFAULT enable_networking = -1 %]

```

will override value `0` specified on the command-line. (It sees a `enable_networking` is false and sets it to -1)

Are there any easy work-arounds (some config variable maybe?)
['https://Stackoverflow.com/questions/60384568', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/12312873/']
To check if a variable is undefined or not you could check if its `size` method returns something greater than 0. Of course this case only aplies if the variable is not initialized or defined at all (`enable_networking = ''` has size = 1, the same with `enable_networking = 0`)

To check if a variable is not false... well... first you have to describe wich type of value is false.

In this case i will take size = 0 (or size doesn't exists) as undefined, -1 as false and everything else as true:

```
[% IF enable_networking.size and enable_networking != -1 %]
    enable_networking = [% enable_networking %]
[% ELSE %]
    -- a comment, variable enable_networking not provided
[% END %]

```

With the code above if you run

```
render template.tt enable_networking 0

```

The output will be `enable_networking = 0`

And if you run

```
render template.tt

```

The output will be `-- a comment, variable enable_networking not provided` even if you don't declare `[% DEFAULT enable_networking = -1 %]`

**EDIT 1:**

The `length` method is better suited for this job:

```
[% IF enable_networking.length and enable_networking != -1 %]
    enable_networking = [% enable_networking %]
[% ELSE %]
    -- a comment, variable enable_networking not provided
[% END %]

```

Using `length` instead of `size` also allows you to use `enable_networking = ''` as FALSE along with -1

**EDIT 2:**

Ok, after the comments i found a workaround that do the trick: the `TRY` - `CATCH` directives...

For optional variables that can have value of 0 the objective would be to `TRY` setting the variable value to itself, if the variable is defined the value will be assigned, otherwise we `CATCH` the undef error and set the default value. For any other type of variable we can use the `DEFAULT` directive:

```
[% DEFAULT
    hostname = 0
%]
[% TRY %] [% enable_networking = enable_networking %] [% CATCH %] [% enable_networking = -1; %] [% END %]

hostname = [% hostname %]
[% IF enable_networking != -1 AND enable_networking.length %] enable_networking = [% enable_networking %][% ELSE %]-- variable enable_networking not provided[% END %]

```

With this new template if you run

```
$ render template.tt
hostname = 0
-- variable enable_networking not provided

$ render template.tt enable_networking ""
hostname = 0
-- variable enable_networking not provided

$ render template.tt hostname myhost enable_networking 0
hostname = myhost
enable_networking = 0

```
All scalar values in TT have a `.defined` vmethod.

```
[% IF hostname.defined %] hostname = [% hostname %][% ELSE %][% -- a comment, variable hostname not provided %][% END %]

```

This is discussed in [the manual](https://metacpan.org/pod/distribution/Template-Toolkit/lib/Template/Manual/VMethods.pod#defined).