Default value on i.e. string is not working as expected.
corex opened this issue · comments
Version:
v1.2.3
Bug Description
When expecting a string with a default value set, the default value is only returned when key does not exist in data array. I would expect it would return default value "string()" when I have specified null in property "test" in data array. The property "test" is not nullable on purpose, because default value should be returned instead.
$config = new Configuration([
'test' => Expect::string('hey')
]);
$config->merge([
'test' => null,
]);
$value = $config->get('test');
The exception I get is
Uncaught Nette\Schema\ValidationException: The item 'test' expects to be string, null given.
Expected Behavior
I would expect the variable $value
would be equal to "hey".
I think the problem is in the loop at master:src/Schema/Elements/Structure.php:175.
Whole purpose of validator is to accept only expected values. If you don't want to accept null value, just don't send the key at all. Or allow null:
$config = new Configuration([
'test' => Expect::anyOf(Expect::string(), Expect::null())->default(null)
]);
$config->merge([
'test' => null,
]);
$value = $config->get('test') ?? 'hey';
(example assumes you use thephpleague/config wrapper as it seems so)
Hi,. Yes, forgot to menchion league/config :(
Apparently I am wrong in my understanding of default value.... I can set it as nullable, but then I have to take care of handling default value for both Except::class and in my own code. I am planning to write a wrapper of my own, so to maintain a default value two places is not good.
I am planning to have a config file with all properties in array with comments on i.e. https://github.com/laravel/laravel/blob/9.x/config/database.php
I am only using Laravel as an example. In this file you will see many properties with "null" specified. I need to have something similar and thought I found GOLD :D
A variable containing null is an indication that the variable is not set. From my understanding the default() should apply here - hence my bug report. If it is a design choice
, this bug report should be closed.
I can work around it by always setting Expect::.... to nullable() and handle the default values myself. That way I handle both the missing key in the array and if the key in the array is set to null - in my own code. In my opinion, this should not be necessary.
I might consider making this a feature request instead....
A variable containing null is an indication th
I don't think so. Take a look at this configuration:
debug:
logfile: null
Does this mean 1) disable logging or 2) use the default file? I think a lot of people would be confused if it behaved as 2). If I want to use the default behavior, I don't mention the key in config at all. When I mention it, it means I want to change something.
However, the behaviour you want to achieve is very easy to do:
function ignoreNulls($data)
{
return array_filter($data, fn($val) => !is_null($val));
}
$schema = Expect::structure([
'test' => Expect::type('string|null')->default('def'),
])->before('ignoreNulls');
Based on your answer, I can conclude it is a design choice.
About the 1 & 2. I agree it can be confusing, but then I would argue that there is missing some comments in the yaml-file itself. And after reading both of your comments again, I think the best approach for me is simply to add comments in the file and comment out the "variable".
Thanks for the tip.