Ask

 view release on metacpan or  search on metacpan

lib/Ask.pm  view on Meta::CPAN

		or not @implementations )
	{
		@implementations = use_module( 'Ask::Fallback' );
	}
	
	my @traits = @{ delete( $args{traits} ) || [] };
	for my $i ( @implementations ) {
		my $k    = @traits ? "Moo::Role"->create_class_with_roles( $i, @traits ) : $i;
		my $self = eval { $k->new( { %args, %{ $args{$i} or {} } } ) } or next;
		return $self if $self->is_usable;
	}
	
	croak "No usable backend for Ask";
} #/ sub detect

sub Q {
	require Ask::Question;
	'Ask::Question'->new( @_ );
}

my $instance;
sub instance {
	shift;
	@_ ? ( $instance = $_[0] ) : ( $instance ||= __PACKAGE__->detect );
}

1;

__END__

=head1 NAME

Ask - ask your users about stuff

=head1 SYNOPSIS

Object-oriented style:

   use Ask;
   
   my $ask = Ask->detect;
   
   if ($ask->question(text => "Are you happy?")
   and $ask->question(text => "Do you know it?")
   and $ask->question(text => "Really want to show it?")) {
      $ask->info(text => "Then clap your hands!");
   }

Functional style:

   use Ask ':all';
   
   if (question("Are you happy?")
   and question("Do you know it?")
   and question("Really want to show it?")) {
      info("Then clap your hands!");
   }

=head1 DESCRIPTION

The C<Ask> suite is a set of modules for interacting with users; prompting
them for information, displaying messages, warnings and errors, etc.

There are already countless CPAN modules for doing this sort of thing, but
what sets C<Ask> apart from them is that C<Ask> will detect how your script
is being run (in a terminal, headless, etc) and choose an appropriate way
to interact with the user.

=head2 Class Methods

=over

=item C<< Ask->instance >>

Singleton pattern. Can also be passed an argument to use it as a setter.

=item C<< Ask->detect(%arguments) >>

A constructor, sort of. It inspects the program's environment and returns an
object that implements the Ask API (see below).

Backend-specific arguments can be provided:

  my $ask = Ask->detect(
    %common_args,
    'Ask::STDIO'  => \%stdio_args,
    'Ask::Zenity' => \%zenity_args,
  );

Note that these objects don't usually inherit from C<Ask>, so the following
will typically be false:

   my $ask = Ask->detect(%arguments);
   $ask->isa("Ask");

Instead, check:

   my $ask = Ask->detect(%arguments);
   $ask->DOES("Ask::API");

=item C<< Ask->backends >>

Returns a list of available backends. Each backend is a Perl class name. Some
of the backends may be available (i.e. installed and able to be compiled)
without being usable under current circumstances (e.g. the Gtk2 backend is
available but cannot be used because no X server is running). To check
usability, instantiate the class and call C<is_usable> on the instance.

The list is sorted in "quality" order, best to worst, though quality is
subjective.

=item C<< Ask->plugins >>

The same as C<< Ask->backends >>, but doesn't check that each result is a
loadable Perl class, and doesn't sort them in any particular order.

=back

=head2 The Ask API

Objects returned by the C<detect> method implement the Ask API. This



( run in 2.521 seconds using v1.01-cache-2.11-cpan-6aa56a78535 )