From 134452e7911d041c3429516bfc9226f1b2aacaf1 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Fri, 6 Apr 2018 00:25:24 +0200 Subject: [PATCH 1/4] Add 2 solutions for the 'option with optional argument' problem --- console/input.rst | 83 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 15 deletions(-) diff --git a/console/input.rst b/console/input.rst index 1a0f3dc22a9..d571e4a4c18 100644 --- a/console/input.rst +++ b/console/input.rst @@ -179,6 +179,15 @@ values after a white space or an ``=`` sign (e.g. ``--iterations 5`` or ``--iterations=5``), but short options can only use white spaces or no separation at all (e.g. ``-i 5`` or ``-i5``). +.. caution:: + + While it is possible to separate an option from its value with a white space, + using this form leads to an ambiguity should the option appear before the + command name. For example, ``php app/console --iterations 5 app:greet Fabien`` + is ambiguous; Symfony would interpret ``5`` as the command name. To avoid + this situation, always place options after the command name, or avoid using + a space to separate the option name from its value. + There are four option variants you can use: ``InputOption::VALUE_IS_ARRAY`` @@ -209,25 +218,69 @@ You can combine ``VALUE_IS_ARRAY`` with ``VALUE_REQUIRED`` or array('blue', 'red') ); -.. tip:: +Options with optional arguments +------------------------------- - There is nothing forbidding you to create a command with an option that - optionally accepts a value. However, there is no way you can distinguish - when the option was used without a value (``command --language``) or when - it wasn't used at all (``command``). In both cases, the value retrieved for - the option will be ``null``. +There is nothing forbidding you to create a command with an option that +optionally accepts a value, but it's a bit tricky. Let's use this +option definition as an example:: - Similarly, due to a PHP limitation, there is no way to pass an empty string - as the value of an option. In ``command --prefix`` and ``command --prefix=''`` - cases, the value of the ``prefix`` option will be ``null``. + // ... + use Symfony\Component\Console\Input\InputOption; + + $this + // ... + ->addOption( + 'yell', + null, + InputOption::VALUE_OPTIONAL, + 'Should I yell while greeting?' + ); + +We want to use this option in 3 ways: ``--yell``, ``yell=louder``, and not +passing the option at all; however, the task of distinguishing between when +the option was used without a value (``greet --yell``) or when it wasn't used +at all (``greet``) it's a bit impervious. + +To solve this issue, you have two possible solutions: in the first case, you +can use the ``hasParameterOption`` method:: + + if ($input->hasParameterOption('--yell')) { + $yell = true; + $yellLouder = $input->getOption('yell') === 'louder'; + } .. caution:: - While it is possible to separate an option from its value with a white space, - using this form leads to an ambiguity should the option appear before the - command name. For example, ``php app/console --iterations 5 app:greet Fabien`` - is ambiguous; Symfony would interpret ``5`` as the command name. To avoid - this situation, always place options after the command name, or avoid using - a space to separate the option name from its value. + Note that the ``hasParameterOption`` method requires prepending ``--`` + to the option name. + +The second solution is to alter the option definition, setting the default value +to ``false``:: + + // ... + use Symfony\Component\Console\Input\InputOption; + + $this + // ... + ->addOption( + 'yell', + null, + InputOption::VALUE_OPTIONAL, + 'Should I yell while greeting?', + false // this is the new default value, instead of null + ); + +And then checking carefully the value of the option, minding that ``false !== null``:: + + $optionValue = $input->getOptions('yell'); + $yell = ($optionValue !== false); + $yellLouder = ($optionValue === 'louder'); + +.. caution:: + + Due to a PHP limitation, passing an empty string is indistinguishable from + not passing any value at all. In ``command --prefix`` and ``command --prefix=''`` + cases, the value of the ``prefix`` option will be ``null``. .. _`docopt standard`: http://docopt.org/ From 97b6e901f70de1ef766c61e55ce9e1fed9700a28 Mon Sep 17 00:00:00 2001 From: Alessandro Lai Date: Sun, 6 May 2018 22:10:27 +0200 Subject: [PATCH 2/4] Simplify the explanation leaving just one solution --- console/input.rst | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) diff --git a/console/input.rst b/console/input.rst index d571e4a4c18..df83ec23f84 100644 --- a/console/input.rst +++ b/console/input.rst @@ -242,21 +242,7 @@ passing the option at all; however, the task of distinguishing between when the option was used without a value (``greet --yell``) or when it wasn't used at all (``greet``) it's a bit impervious. -To solve this issue, you have two possible solutions: in the first case, you -can use the ``hasParameterOption`` method:: - - if ($input->hasParameterOption('--yell')) { - $yell = true; - $yellLouder = $input->getOption('yell') === 'louder'; - } - -.. caution:: - - Note that the ``hasParameterOption`` method requires prepending ``--`` - to the option name. - -The second solution is to alter the option definition, setting the default value -to ``false``:: +To solve this issue, you have to set the option's default value to ``false``:: // ... use Symfony\Component\Console\Input\InputOption; @@ -271,7 +257,8 @@ to ``false``:: false // this is the new default value, instead of null ); -And then checking carefully the value of the option, minding that ``false !== null``:: +And then you just have to check carefully the value of the option, minding that +``false !== null``:: $optionValue = $input->getOptions('yell'); $yell = ($optionValue !== false); From ee1d3a7f2408f354c93717557df127c588045abe Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sun, 27 May 2018 12:55:17 +0200 Subject: [PATCH 3/4] Minor reword --- console/input.rst | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/console/input.rst b/console/input.rst index df83ec23f84..dfa2d4fc616 100644 --- a/console/input.rst +++ b/console/input.rst @@ -237,10 +237,9 @@ option definition as an example:: 'Should I yell while greeting?' ); -We want to use this option in 3 ways: ``--yell``, ``yell=louder``, and not -passing the option at all; however, the task of distinguishing between when -the option was used without a value (``greet --yell``) or when it wasn't used -at all (``greet``) it's a bit impervious. +This option can be used in 3 ways: ``--yell``, ``yell=louder``, and not passing +the option at all. However, it's hard to distinguish between passing the option +without a value (``greet --yell``) and not passing the option (``greet``). To solve this issue, you have to set the option's default value to ``false``:: From bde672d4624824a3708baff8592a5e5237759919 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Sun, 27 May 2018 13:01:06 +0200 Subject: [PATCH 4/4] Minor simplifications --- console/input.rst | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/console/input.rst b/console/input.rst index dfa2d4fc616..5be9a00baad 100644 --- a/console/input.rst +++ b/console/input.rst @@ -222,8 +222,7 @@ Options with optional arguments ------------------------------- There is nothing forbidding you to create a command with an option that -optionally accepts a value, but it's a bit tricky. Let's use this -option definition as an example:: +optionally accepts a value, but it's a bit tricky. Consider this example:: // ... use Symfony\Component\Console\Input\InputOption; @@ -256,8 +255,7 @@ To solve this issue, you have to set the option's default value to ``false``:: false // this is the new default value, instead of null ); -And then you just have to check carefully the value of the option, minding that -``false !== null``:: +Now check the value of the option and keep in mind that ``false !== null``:: $optionValue = $input->getOptions('yell'); $yell = ($optionValue !== false);