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 |