Thread: [Module::Build] ask() and you will receive
Status: Beta
Brought to you by:
kwilliams
|
From: Randy W. S. <Ra...@Th...> - 2006-04-08 10:34:08
Attachments:
Prompter.pm
|
Attached is version of the ask() routine discussed earlier to supersede
or augment prompt() and y_n(), including pod. I extracted it directly
out of my working copy of MB and put it in its own package to make it
easier to demo for feedback. It would go in MB along with prompt() and
y_n() if we decide to use it.
Here is a sample driver:
use Prompter;
my $answer;
$answer = Prompter->ask(
prompt => "What is your favorite programming language?\n",
options => [qw(Perl Ruby Lua Python C C++)],
default => 'unknown',
show_options => 1,
show_default => 0,
);
print "Answer: $answer\n";
__END__
Please see `perldoc Prompter.pm` for docs.
Randy.
|
|
From: Ken W. <ke...@ma...> - 2006-04-10 04:08:39
|
I think this is a decent direction. I only have a couple of concerns: one, I do think that the default needs to be one of the options in an option list, or else people are just going to make too many mistakes. Two, maybe we can come up with a better name, just because I don't like classes that end in "er". -Ken On Apr 8, 2006, at 5:32 AM, Randy W. Sims wrote: > Attached is version of the ask() routine discussed earlier to > supersede or augment prompt() and y_n(), including pod. I extracted > it directly out of my working copy of MB and put it in its own > package to make it easier to demo for feedback. It would go in MB > along with prompt() and y_n() if we decide to use it. > > Here is a sample driver: > > use Prompter; > > my $answer; > $answer = Prompter->ask( > prompt => "What is your favorite programming language?\n", > options => [qw(Perl Ruby Lua Python C C++)], > default => 'unknown', > show_options => 1, > show_default => 0, > ); > > print "Answer: $answer\n"; > > __END__ > > Please see `perldoc Prompter.pm` for docs. > > Randy. > > <Prompter.pm> |
|
From: Randy W. S. <ml...@th...> - 2006-04-10 07:49:36
|
Ken Williams wrote:
> I think this is a decent direction. I only have a couple of concerns:
> one, I do think that the default needs to be one of the options in an
> option list, or else people are just going to make too many mistakes.
I debated that decision for a while. The reason I allowed it was that
when running an unattended build, none of the choices may be a
reasonable default. In that case the default can be set to an empty
string or something that make sense to indicate that no choice was made.
Note also that 'default' may be set to an empty string or to any value,
including undef as long as something is passed in.
One alternative I can think of:
$answer = Prompter->ask(
prompt => "What is your favorite programming language?\n",
options => [qw(Perl Ruby Lua Python C C++ /unknown/)],
default => 'unknown',
);
Another element is added to 'options' enclosed between slashes (or
something). Such elements would not be show when options are displayed.
Then default can be set to the "invisible" option.
> Two, maybe we can come up with a better name, just because I don't like
> classes that end in "er".
Actually, I intended this code to be in Module::Build::Base. I just
extracted it to make it easy to review. So actual usage would be:
use Module::Build
my $mb = Module::Build->new(...);
$mb->ask(...);
-or-
Module::Build->ask(...);
Randy.
|
|
From: Randy W. S. <ml...@th...> - 2006-04-11 09:24:19
|
Randy W. Sims wrote:
> Ken Williams wrote:
>
>> I think this is a decent direction. I only have a couple of
>> concerns: one, I do think that the default needs to be one of the
>> options in an option list, or else people are just going to make too
>> many mistakes.
>
>
> I debated that decision for a while. The reason I allowed it was that
> when running an unattended build, none of the choices may be a
> reasonable default. In that case the default can be set to an empty
> string or something that make sense to indicate that no choice was made.
>
> Note also that 'default' may be set to an empty string or to any value,
> including undef as long as something is passed in.
>
> One alternative I can think of:
>
> $answer = Prompter->ask(
> prompt => "What is your favorite programming language?\n",
> options => [qw(Perl Ruby Lua Python C C++ /unknown/)],
> default => 'unknown',
> );
>
> Another element is added to 'options' enclosed between slashes (or
> something). Such elements would not be show when options are displayed.
> Then default can be set to the "invisible" option.
The only bad thing is open ended questions get a little more verbose.
Instead of:
$answer = Prompter->ask(
prompt => "What is your user name?\n",
default => 'guest',
);
You would have to say:
$answer = Prompter->ask(
prompt => "What is your user name?\n",
options => ['/guest/'],
default => 'guest',
);
Another options would be to require the user to flag the default if it
is not in the options list. In effect, the user must declare she knows
the string entered is not in the options and that she knows exactly what
she's doing.
$answer = Prompter->ask(
prompt => "What is your user name?\n",
default => '!guest',
);
(The first character of the default string is an exclamation mark.)
Opinions?
Randy.
|
|
From: David W. <da...@ki...> - 2006-04-11 14:40:23
|
On Apr 11, 2006, at 02:23, Randy W. Sims wrote: > The only bad thing is open ended questions get a little more > verbose. Instead of: > > $answer = Prompter->ask( > prompt => "What is your user name?\n", > default => 'guest', > ); > > You would have to say: > > $answer = Prompter->ask( > prompt => "What is your user name?\n", > options => ['/guest/'], > default => 'guest', > ); That seems silly. Why force them to use options if it's open-ended? > Another options would be to require the user to flag the default if > it is not in the options list. In effect, the user must declare she > knows the string entered is not in the options and that she knows > exactly what she's doing. Yeah, that'd be okay. > $answer = Prompter->ask( > prompt => "What is your user name?\n", > default => '!guest', > ); > > (The first character of the default string is an exclamation mark.) Why use a mini-language? Why not just another parameter? yes_i_know_default_isnt_in_options => 1, ? Best, David |
|
From: Randy W. S. <ml...@th...> - 2006-04-11 22:33:05
|
David Wheeler wrote: > On Apr 11, 2006, at 02:23, Randy W. Sims wrote: > >> Another options would be to require the user to flag the default if it >> is not in the options list. In effect, the user must declare she knows >> the string entered is not in the options and that she knows exactly >> what she's doing. > > Yeah, that'd be okay. > >> $answer = Prompter->ask( >> prompt => "What is your user name?\n", >> default => '!guest', >> ); >> >> (The first character of the default string is an exclamation mark.) > > Why use a mini-language? Why not just another parameter? > > yes_i_know_default_isnt_in_options => 1, Ok, I think I'm having one of those "what was I thinking (or drinking)?" moments. Yep, feeling rather foolish now. Any ideas on how to best abbreviate 'yes_i_know_default_isnt_in_options'? allow_nonoption_default allow_odd_default I'm going to try my best to get this one wrapped up and committed tonight, possibly including some of the mentioned extensions. Randy. |
|
From: David W. <da...@ki...> - 2006-04-11 23:06:12
|
On Apr 11, 2006, at 15:32, Randy W. Sims wrote: > Any ideas on how to best abbreviate > 'yes_i_know_default_isnt_in_options'? > > allow_nonoption_default > allow_odd_default nonoption_default_ok? > I'm going to try my best to get this one wrapped up and committed > tonight, possibly including some of the mentioned extensions. Cool. David |
|
From: Randy W. S. <ml...@th...> - 2006-04-14 09:46:20
Attachments:
ask.diff
|
David Wheeler wrote: > On Apr 11, 2006, at 15:32, Randy W. Sims wrote: > >> I'm going to try my best to get this one wrapped up and committed >> tonight, possibly including some of the mentioned extensions. > > > Cool. I missed my deadline. Attached is my working patch, tests included. I didn't implement the config file or environment variable checking. I don't really see them as being generally applicable. They're more specialized, and the behavior can be supplied easily enough by the author before calling ask(). The only thing I plan to add is the on_validate callback mentioned earlier. I'm still debating the best time/circumstances to invoke the callback. Randy. |
|
From: David W. <da...@ki...> - 2006-04-14 16:06:18
|
On Apr 14, 2006, at 02:44, Randy W. Sims wrote: > +=item ask() > + > +[version 0.28] > + > +Asks the user a question and returns the answer as a string. > + > +The following is a list of arguments. Only C<prompt> and C<default> > +are required. > + > +=over > + > +=item allow_nonoption_default > I'd make this last. I tend to list options in the order of importance. So for this method, I would list them in this order: =prompt =default =show_default =options =getopts_name =show_options =allow_nonoption_default > +Normally, the value of the C<default> arguement must exist in the > +C<options> array. But only if there *is* an options array. > Setting this to true allows the C<default> argument > +to be set to an arbitrary value. > + > +=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. But only if there *is* an options parameter and you've set allow_noniption_dfault to true. > +=item show_default > + > +A boolean value that indicates whether the default value should be > +displayed as part of the prompt. If true and if the default is a > +non-empty string, And non-undef? > =item autosplit_file($from, $to) > > [version 0.28] > @@ -1437,6 +1514,8 @@ > > [version 0.12] > > +[Deprecated] See the C<ask()> method. > + What's deprecated, here? Best, David |
|
From: Ron S. <ro...@sa...> - 2006-04-15 02:40:32
|
On Fri, 14 Apr 2006 09:05:57 -0700, David Wheeler wrote: Hi David > I'd make this last. I tend to list options in the order of > importance. So for this method, I would list them in this order: What /you/ think is important :-)! I'd prefer them in alphabetical order, for obvious reasons. -- Cheers Ron Savage, ro...@sa... on 15/04/2006 http://savage.net.au/index.html Let the record show: Microsoft is not an Australian company |
|
From: David G. <da...@hy...> - 2006-04-15 12:06:25
|
Ron Savage wrote: > I'd prefer them in alphabetical order, for obvious reasons. I concur. For a while now, I've even been doing this in my code. All functions get organized alphabetically, though I do group them into public, private, capitalized, etc. I never have to wonder something is. Regards, David Golden |
|
From: Ken W. <ke...@ma...> - 2006-04-17 22:09:41
|
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.
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.
> +
> +=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
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
}
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.
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?
> +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?
-Ken
|
|
From: John P. <jpe...@ro...> - 2006-04-18 00:37:37
|
Ken Williams wrote: > 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 also think this is needless frippery, but for the opposite reason. How's this for an alternative definition: The C<options> array is the list of displayed/prompted options to C<ask()> which a user can choose from; C<ask()> will not return until one of these values has been chosen. The C<default> can either be one of the members of C<options> or some value to indicate that no answer could be obtained (such as would be the case if the Build.PL script had no controlling terminal). As such, the union of the C<default> value with the C<options> array is the list of B<permissible> values, whereas the C<options> array is the list of values which satify an interactive C<ask()>. This gets us both: a) the total list of acceptable values, and b) a way to know for certain that the Build.PL script is running unmanned. I don't see any reason to special case the $default <not-in> @options for a flag when we can infer it directly. John -- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4720 Boston Way Lanham, MD 20706 301-459-3366 x.5010 fax 301-429-5747 |
|
From: Randy W. S. <ml...@th...> - 2006-04-18 20:04:11
|
John Peacock wrote: > Ken Williams wrote: > >>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 also think this is needless frippery, but for the opposite reason. How's this > for an alternative definition: > > The C<options> array is the list of displayed/prompted options to C<ask()> which > a user can choose from; C<ask()> will not return until one of these values has > been chosen. The C<default> can either be one of the members of C<options> or > some value to indicate that no answer could be obtained (such as would be the > case if the Build.PL script had no controlling terminal). As such, the union of > the C<default> value with the C<options> array is the list of B<permissible> > values, whereas the C<options> array is the list of values which satify an > interactive C<ask()>. > > This gets us both: > > a) the total list of acceptable values, and > b) a way to know for certain that the Build.PL script is running unmanned. (b) is not possible. If the user presses <enter> or <ctrl-d> without typing anything, then the default will be used. So it's not an indicator of an unattended build. > I don't see any reason to special case the $default <not-in> @options for a flag > when we can infer it directly. IIUC, Ken's original point was that the 'default' argument could be mistyped. Requiring the argument to 'default' to also appear in the 'options' array is a safeguard and requires the author to verify or explicitly allow the differing value. I strongly agree with this; I like "safe" APIs. The union of 'default' and 'options' does constitute the exclusive list of permissible values. It's just that 'default' must be explicitly declared to be different if it is not a member of 'options'. Randy. |
|
From: John P. <jpe...@ro...> - 2006-04-18 20:33:20
|
Randy W. Sims wrote: > (b) is not possible. If the user presses <enter> or <ctrl-d> without > typing anything, then the default will be used. So it's not an indicator > of an unattended build. I thought that M::B already knew whether or not the Build.PL was running unattended or not. AFAIUI, there are three modes: 1) the user types something - it has to match one of the entries in @options (and ask() helpfully prompts with the list of allowed values); 2) the user types nothing (<enter> or <ctrl-d>) - the value of default (or "" if none is set) is returned; 3) the script is running unattended - same effect as #2. If M::B can know whether it is executing in mode #3, then the code can differentiate between #2 and #3 already. What is the use case for a default value being something other than one of the prompted values if not to determine whether the script is unmanned or the user wants the code to make it's best guess (which should be the same thing)? > IIUC, Ken's original point was that the 'default' argument could be > mistyped. Requiring the argument to 'default' to also appear in the > 'options' array is a safeguard and requires the author to verify or > explicitly allow the differing value. I strongly agree with this; I like > "safe" APIs. Having been the unwitting victim of Cut/Paste error before, I don't give much weight to "type the same [possibly long] string here, too" types of constraints. > The union of 'default' and 'options' does constitute the exclusive list > of permissible values. It's just that 'default' must be explicitly > declared to be different if it is not a member of 'options'. That's the leap I'm not making. If the author set a default value that represents a "best guess" option that is different than one of the manually typed options, why does there need to be a flag that indicates that this is a valid value too. A simple comparison between the members of @options and $default already indicates that something else is going on. John -- John Peacock Director of Information Research and Technology Rowman & Littlefield Publishing Group 4501 Forbes Boulevard Suite H Lanham, MD 20706 301-459-3366 x.5010 fax 301-429-5748 |
|
From: Ken W. <ke...@ma...> - 2006-04-18 21:33:40
|
On Apr 18, 2006, at 3:33 PM, John Peacock wrote:
> If M::B can know whether it is executing in mode #3, then the code
> can differentiate between #2 and #3 already. What is the use case
> for a default value being something other than one of the prompted
> values if not to determine whether the script is unmanned or the
> user wants the code to make it's best guess (which should be the
> same thing)?
One use case is when there's really no finite set of permissible
values. For example:
prompt("What username should I use?", $ENV{USER});
prompt("Generate how many fropps per second?", 80);
prompt("Where is libfoo.a?", '/usr/lib');
Perhaps all three of those would benefit from a validation callback,
though.
> That's the leap I'm not making. If the author set a default value
> that represents a "best guess" option that is different than one of
> the manually typed options, why does there need to be a flag that
> indicates that this is a valid value too. A simple comparison
> between the members of @options and $default already indicates that
> something else is going on.
On the one hand, the author might typo the default and not realize
it, and the explicit flag helps protect them against that. On the
other hand, they could accidentally typo the name of the flag too,
but at least theoretically we could detect that.
-Ken
|
|
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.
|
|
From: Randy W. S. <ml...@th...> - 2006-04-19 08:51:14
|
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. > > 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. I've done this as well as implemented the 'on_validate' callback. The callback return value behavior is a little weird, but it's the least weird I could think of at the moment. Overall, I think it will work well. I've gone ahead and comitted what I have as an initial implementation to give something concrete to play with, and as a base with which to experiment with the other remaining issues. Randy. |
|
From: Ken W. <ke...@ma...> - 2006-04-20 02:02:18
|
On Apr 19, 2006, at 3:50 AM, Randy W. Sims wrote: > I've gone ahead and comitted what I have as an initial > implementation to give something concrete to play with, and as a > base with which to experiment with the other remaining issues. Thanks, Randy. I'll play around with it some. If you see me make some change you don't like, be sure to let me know. -Ken |
|
From: Randy W. S. <ml...@th...> - 2006-04-20 00:08:54
Attachments:
ask.diff
|
Ken Williams wrote:
>
> On Apr 14, 2006, at 4:44 AM, Randy W. Sims wrote:
>
>> +
>> +=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
>
> 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
> }
>
> 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.
>
> 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?
Here's a rough rough patch to implement something along those lines, I
think. Rough day, my brains not working well, and somehow this simple
little input routine has become one of the largest routines in M::B, so
I'd appreciate feedback. All names, behaviors, and every last byte
subject to change.
Randy.
|
|
From: Randy W. S. <ml...@th...> - 2006-04-24 05:35:27
|
Randy W. Sims wrote:
> Ken Williams wrote:
>
>> On Apr 14, 2006, at 4:44 AM, Randy W. Sims wrote:
>>
>>> +
>>> +=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
>>
>> 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
>> }
>>
>> 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.
>>
>> 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?
>
>
> Here's a rough rough patch to implement something along those lines, I
> think. Rough day, my brains not working well, and somehow this simple
> little input routine has become one of the largest routines in M::B, so
> I'd appreciate feedback. All names, behaviors, and every last byte
> subject to change.
Anyone have a chance to look over that patch? Does it do the right
thing? Is it the behavior that was desired, and is it sensisble?
Randy.
|
|
From: Ken W. <ke...@ma...> - 2006-04-27 02:41:21
|
On Apr 24, 2006, at 12:35 AM, Randy W. Sims wrote: >> Here's a rough rough patch to implement something along those >> lines, I think. Rough day, my brains not working well, and somehow >> this simple little input routine has become one of the largest >> routines in M::B, so I'd appreciate feedback. All names, >> behaviors, and every last byte subject to change. > > Anyone have a chance to look over that patch? Does it do the right > thing? Is it the behavior that was desired, and is it sensisble? I did have a look a couple of times, and I just keep feeling like we're creating something too complicated. And that we're delaying 0.28 again. =( How's this proposal: let's keep the patch for ask() in the wings, and release 0.28 without it. There's no real burning need for it, now that y_n() and prompt() behave better in non-interactive mode. Hopefully we can speed up the release schedule for things after 0.28, and we can plop ask() into one of those releases when we're happy with it. -Ken |
|
From: Randy W. S. <ml...@th...> - 2006-04-27 23:23:01
|
Ken Williams wrote: > > On Apr 24, 2006, at 12:35 AM, Randy W. Sims wrote: > >>> Here's a rough rough patch to implement something along those lines, >>> I think. Rough day, my brains not working well, and somehow this >>> simple little input routine has become one of the largest routines in >>> M::B, so I'd appreciate feedback. All names, behaviors, and every >>> last byte subject to change. >> >> Anyone have a chance to look over that patch? Does it do the right >> thing? Is it the behavior that was desired, and is it sensisble? > > I did have a look a couple of times, and I just keep feeling like we're > creating something too complicated. And that we're delaying 0.28 again. =( > > How's this proposal: let's keep the patch for ask() in the wings, and > release 0.28 without it. There's no real burning need for it, now that > y_n() and prompt() behave better in non-interactive mode. Hopefully we > can speed up the release schedule for things after 0.28, and we can plop > ask() into one of those releases when we're happy with it. At this point, I think I'd be very happy with that. Otherwise, there might soon be a full revolt. I apologize to everyone for not being more on top of things; it's difficult sometimes to manage between God, family, work, this, and other responsibilities. I very much envy those guys that can work full time jobs and still turn out gobs of code every day. Other than pulling the ask() method out along with it's documentation, is there anything else I need to do before release? I don't think we have any bugs that are more pressing than getting a release out are there? Randy. |
|
From: Ken W. <ke...@ma...> - 2006-04-28 02:23:11
|
On Apr 27, 2006, at 6:22 PM, Randy W. Sims wrote: > At this point, I think I'd be very happy with that. Otherwise, > there might soon be a full revolt. I apologize to everyone for not > being more on top of things; it's difficult sometimes to manage > between God, family, work, this, and other responsibilities. I very > much envy those guys that can work full time jobs and still turn > out gobs of code every day. You're telling me! I can barely get my laptop opened these days. > Other than pulling the ask() method out along with it's > documentation, is there anything else I need to do before release? > I don't think we have any bugs that are more pressing than getting > a release out are there? I think that's about it too. I see you've already yanked out ask(), I'll poke & prod the distribution a little and if I don't see any obstacles I'll nonchalantly release 0.28 tonight. -Ken |
|
From: David W. <da...@ki...> - 2006-04-10 05:02:29
|
On Apr 8, 2006, at 03:32, Randy W. Sims wrote:
> my $answer;
> $answer = Prompter->ask(
> prompt => "What is your favorite programming language?\n",
> options => [qw(Perl Ruby Lua Python C C++)],
> default => 'unknown',
> show_options => 1,
> show_default => 0,
> );
>
> print "Answer: $answer\n";
This actually looks similar to a method I wrote in my subclass. I
think that you might find my "environ" and "callback" options useful
additions:
=head3 get_reply
my $value = $build->get_reply(%params);
Prompts the user with a message, and then collects a value from the
user (if there is a TTY). A number of options can be specified, and
the method will display a numbered list from which the user to select
a value. Callbacks can also be specified to ensure the quality of a
value.
The supported parameters are:
=over
=item message
A message with which to prompt the user, such as "What is your
favorite color?".
=item name
The name of the Kinetic::Build::Base property or argument stored in
the Module::Build C<args()> for which a value is sought. Optional. If
the value was specified on the command-line, the user will not be
prompted for a value.
=item label
A label for the value you're attempting to collect, such as "Favorite
color".
=item default
A default value. This will be used if the user accepts the value (by
hitting) enter or control-D), and will be returned without prompting
the user if the C<accept_defaults> property is set to a true value or
if there is no TTY.
=item options
An array reference of possible values from which the user can select.
=item callback
A code reference that validates a value input by a user. The value to
be checked will be passed in as the first argument and will also be
stored in C<$_>. For example, if you wanted to ensure that a value
was an integer, you might pass a code reference like C<sub { /^\d+$/ }
>. Note that if the callback sets C<$_> to a different value, the
revised value is the one that will be returned. This can be useful
for parsing one value from another.
=item config_keys
An array reference with two values that will be used to look up the
value in the configuration file specified by the C<path_to_config>
property. If no config file has been specified, these values will not
be used. Otherwise, if no value was found in the Module::Build
runtime parameters or arguments, the configuration file will be
consulted. The first item in the array should be the name of the
config file label, and the second item should be the key for the
value for that label. For example, if you wanted to get at the store
class, it might appear in the config file like so:
[store]
class: Kinetic::Store::DB::Pg
To retrieve that value, set the array reference to ['store', 'class'].
=item environ
The name of an environment variable to check for a value. Checked
only after the Module::Build runtime parameters and arguments and the
configuration file have failed to return a value, but before
prompting the user.
Best,
David
|