Re: [Module::Build] ask() and you will receive
Status: Beta
Brought to you by:
kwilliams
|
From: Randy W. S. <ml...@th...> - 2006-04-18 19:51:29
|
Ken Williams wrote:
>
> On Apr 14, 2006, at 4:44 AM, Randy W. Sims wrote:
>
>> +
>> +=item allow_nonoption_default
>> +
>> +Normally, the value of the C<default> arguement must exist in the
>> +C<options> array. Setting this to true allows the C<default> argument
>> +to be set to an arbitrary value.
>
>
> I do still wonder about the need for this parameter. The author could
> just as easily put the value in the options array, and probably with
> less typing.
I was theorizing that sometimes the default would be some value that the
author would not necessarily want to show up in the list of options as
displayed to the user:
$mb->ask(prompt => 'Does Randy ever finish when he says he will?',
options => [qw(yes no)],
default => 'never',
allow_nonoption_default => 1,
);
The options 'yes' and 'no' will appear to the user, while the default
value will not appear in the list:
Does Randy ever finish when he says he will? (yes/no)
I *do* hate typing 'allow_nonoption_default' though, or any extra
arguement. I think I liked the exclamation as the first character of the
default string for convenience.
$mb->ask(prompt => 'Does Randy ever finish when he says he will?',
options => [qw(yes no)],
default => '!never',
);
But it's more obscure, and removes the ability to set 'default' to undef().
> Not a big deal, though.
>
> Let's at least update the verbiage to read something like this,
> indicating that C<options> isn't required:
>
> +=item allow_nonoption_default
> +
> +Normally, if an C<options> array is present, then the value of the
> C<default>
> +argument must exist in C<options>. Setting C<allow_nonoption_default>
> to true
> +allows the C<default> argument to be set to an arbitrary value.
Current implementation is that 'default' is required to be in 'options'
unless 'allow_nonoption_default' is set, regardless of whether the
'options' argument is provided or not. I guess it would make sense to
omit this requirement if no 'options' are defined.
>> +
>> +=item default [required]
>> +
>> +This is the default value that will be used if the user presses
>> +E<lt>enterE<gt> or if running an unattended build.
>> +
>> +The value assigned to C<default> may be different from the options
>> +listed in the C<options> argument.
>
>
> I think I'm about to blaspheme, but I think sometimes we shouldn't
> require there to be a default.
>
> /me ducks
and quacks ;)
That was my entire motivation for this addition, but you're probably
right. I had been thinking something similar, but I wasn't sure whether
it should be a case-by-case arguement to ask(), a constructor arguement,
or a simple global accessor.
> Sometimes there's simply no way to build & test & install a module
> without user intervention. For example, Inline::Java asks you to tell
> it where the J2SDK installation is, and there's no default.
>
> If we changed the error message to something appropriate, I think we
> could handle this case gracefully, both here and in y_n(). Something
> like:
>
> if ( $ENV{PERL_MM_USE_DEFAULT} && !$def ) {
> die <<EOF;
> ERROR: PERL_MM_USE_DEFAULT is in effect, but there is no default
> value. Aborting.
> EOF
> }
That's exactly what we currently do in y_n(). While prompt() always
defaults to an empty string if $def is not provided. I'm thinking ask()
should require a default unless explicitly told otherwise, and I really
do think it should be explicit, otherwise there is not much benefit to
adding ask() over the existing prompt() and y_n().
I'm also not sure that we should rely on PERL_MM_USE_DEFAULT for the
ask() method. As above, I think there should be an explicit statement by
the author that says this build can't be run unattended.
We also need to keep in mind usages like:
open(STDIN, 'answers') or die "$!";
my $mb = Module::Build->new_from_context;
> It might be nice to note this fact in the META.yml file, using a flag
> like 'interactive_install' or something, so that automated testers
> don't even try to download & build the distro.
I think that would be very desirable and it would eliminate some
complaints from testers. Although, I favor 'build' over install:
interactive_build
unattended_build
> For a distro that really requires interaction like this, the author
> could work around our proposed required 'default' by setting 'default'
> to undef and then die()ing with their own error message if prompt() or
> y_n() or ask() returned undef, but why not provide them with the
> appropriate sugar?
Agreed.
>> +A reference to an array containing a list of valid options. If options
>> +are provided, C<ask()> will not return until a valid option is
>> +entered, or the C<default> is selected by pressing E<lt>enterE<gt>
>> +without entering a value. Option names are case-insensitive, but the
>> +option returned will be normalized to the form used in the argument to
>> +C<options>. It is not necessary for the user to enter the entire
>> +option name; C<ask()> will accept any unambiguous sequence of
>> +characters that will match only one option. Eg. If the options are
>> +C<qw(yes no)> it will accept any of 'y', 'ye', or 'yes' to mean
>> +yes. The complete option name will be returned.
>
>
> Maybe we should make this conditional on an option called
> 'allow_abbrev', default true, or something?
Yeah, yeah, add more work. =)
Randy.
|