in reply to Re: installing module starter
in thread installing module starter

That’s because your “hyphens” are actually Unicode minus signs

Oy, I knew something was up when the character went unicode in the c tags. Thank you for taking the time to point it out. I like to preserve the vertical space in my threads for replies, so will put new code, comments, and questions in readmore tags:

I didn't want to begin with that ridiculous keystroke error, but tja. The current options with defaults are worth a reading:

module-starter [options] Options: --module=module Module name (required, repeatable) --distro=name Distribution name (optional) --dir=dirname Directory name to create new module in (optio +nal) --builder=module Build with 'ExtUtils::MakeMaker' or 'Module:: +Build' --eumm Same as --builder=ExtUtils::MakeMaker --mb Same as --builder=Module::Build --mi Same as --builder=Module::Install (discourage +d) --author=name Author's name (taken from getpwuid if not pro +vided) --email=email Author's email (taken from EMAIL if not provi +ded) --ignores=type Ignore type files to include (repeatable) --license=type License under which the module will be distri +buted (default is artistic2) --genlicense Generate LICENSE file according to specified +license --minperl=ver Minimum Perl version required (optional; default is 5.006) --fatalize Generate code that causes all warnings to be +fatal with: use warnings FATAL => 'all' --verbose Print progress messages while working --force Delete pre-existing files if needed --help Show this message $

I created it in the following directory with the following command:

$ pwd /home/bob/Documents/meditations/castaways $ ls $ module-starter --module=translate --author="professor" --email=prof@ +island.coconut Added to MANIFEST: Changes Added to MANIFEST: ignore.txt Added to MANIFEST: lib/translate.pm Added to MANIFEST: Makefile.PL Added to MANIFEST: MANIFEST Added to MANIFEST: README Added to MANIFEST: t/00-load.t Added to MANIFEST: t/manifest.t Added to MANIFEST: t/pod-coverage.t Added to MANIFEST: t/pod.t Added to MANIFEST: xt/boilerplate.t Created starter directories and files $ ls translate $ cd translate/ $ ls Changes ignore.txt lib Makefile.PL MANIFEST README t xt $

Now, what will I try to do with this software tool? I thought that an authentic task it could do is translate text. I have written scripts before that do as much. It might be nice to work up a few different ways, but I thought the first best one might be to use the google api:

#!/usr/bin/perl -w use 5.011; use WWW::Google::Translate; use Config::Tiny; use Data::Dumper; use open OUT => ':encoding(UTF-8)', ':std'; use Path::Tiny; my $ini_path = qw( /home/bob/Documents/html_template_data/3.values.ini + ); say "ini path is $ini_path"; my $tempfile = Path::Tiny->tempfile(TEMPLATE => 'trans_XXXXXX', suffix + => '.txt'); my $string_temp = $tempfile->stringify; say "save file is $string_temp"; my $sub_hash = "google"; my $Config = Config::Tiny->new; $Config = Config::Tiny->read( $ini_path, 'utf8' ); #say Dumper $Config; my $von = 'en'; my $zu = 'ru'; # -> is optional between brackets my $key = $Config->{$sub_hash}{'api_key_1'}; my $wgt = WWW::Google::Translate->new( { key => $key, default_source => $von, default_target => $zu, } ); my $r = $wgt->translate( { q => 'I wave my private parts at your aunti +es, you cheesy lot of second hand electric donkey-bottom biters.' } ) +; my $result = ""; for my $trans_rh ( @{ $r->{data}->{translations} } ) { $result = $trans_rh->{translatedText}; print $trans_rh->{translatedText}, "\n"; } say Dumper $r; my $wgt2 = WWW::Google::Translate->new( { key => $key, default_source => $zu, default_target => $von, cache_file => $string_temp, } ); my $s = $wgt2->translate( { q => $result} ); for my $trans_rh ( @{ $s->{data}->{translations} } ) { print $trans_rh->{translatedText}, "\n"; } say Dumper $s; say "------";

This doesn't quite work the way I want yet, because I was trying to re-translate the output back to the original language, and I get something about magic number rather than output there. Using pre-tags here so that the cyrillic characters don't blow up. (We get that representation in the output as well.)

$ ./3.trans_www.pl 
ini path is /home/bob/Documents/html_template_data/3.values.ini
save file is /tmp/trans_LMuE7M.txt
Я машу своими личными частями в твоих тетушек, ты, паршивая подержанная электрическая пила с ослиным дном.
$VAR1 = {
          'data' => {
                      'translations' => 
                                          {
                                            'translatedText' => "\x{42f} \x{43c}\x{430}\x{448}\x{443} \x{441}\x{432}\x{43e}\x{438}\x{43c}\x{438} \x{43b}\x{438}\x{447}\x{43d}\x{44b}\x{43c}\x{438} \x{447}\x{430}\x{441}\x{442}\x{44f}\x{43c}\x{438} \x{432} \x{442}\x{432}\x{43e}\x{438}\x{445} \x{442}\x{435}\x{442}\x{443}\x{448}\x{435}\x{43a}, \x{442}\x{44b}, \x{43f}\x{430}\x{440}\x{448}\x{438}\x{432}\x{430}\x{44f} \x{43f}\x{43e}\x{434}\x{435}\x{440}\x{436}\x{430}\x{43d}\x{43d}\x{430}\x{44f} \x{44d}\x{43b}\x{435}\x{43a}\x{442}\x{440}\x{438}\x{447}\x{435}\x{441}\x{43a}\x{430}\x{44f} \x{43f}\x{438}\x{43b}\x{430} \x{441} \x{43e}\x{441}\x{43b}\x{438}\x{43d}\x{44b}\x{43c} \x{434}\x{43d}\x{43e}\x{43c}."
                                          }
                                        
                    }
        };

Magic number checking on storable file failed at /usr/local/lib/x86_64-linux-gnu/perl/5.26.1/Storable.pm line 414, at /usr/local/share/perl/5.26.1/WWW/Google/Translate.pm line 82.
$ 

Alright, so now I've shown a little code and some output. Let me state that a reasonable test of the efficacy of this software could be that the output be within a certain range of unicode. If something is capitalized in the input and does not translate, I could take a swipe at making the usual orthographic transformations for proper names. I might consider it a pass if 75 percent of it or more gets turned to cyrillic characters.

Where should I put input files? Output files?

How do I turn a script into a package?

Thanks for your comment,

Replies are listed 'Best First'.
Re^3: installing module starter
by bliako (Abbot) on Jun 05, 2019 at 23:47 UTC

    Aldebaran that's cool!

    The question I ask myself at this stage is whether I want all the functionality to go into a script or shall I create some high-level functions or even a class and store into the module. I usually prefer the latter and in most cases a class. For example, in your case you need to read the API key from the configuration each time you send for a translation. That can probably be stored in your class. So you get functionality like:

    use My::Translator; my $trans = My::Translator->new(Config => 'config.txt'); my ($ret, $conf) = $trans->translate("abc xyz"); print "output is '$ret' with confidence $conf %\n";

    but even without a class/OOP you get a nice high-level API like:

    use My::Translator; my $conf = Config::Tiny... my $prep = My::Translator::prepare_with_some_transformations("abc xyz" +); my ($ret, $conf) = My::Translator::translate($prep, $conf); print "output is '$ret' (via $prep) with confidence $conf %\n";

    btw, if you have any scripts you want installed via make install, then insert an EXE_FILES => ['bin/myscript.pl'] into Makefile.PL as a parameter to WriteMakefile() (e.g. just below PL_FILES => {},. In this way make install will install your script(s) along with any module files.

    Edit: I also find useful setting temporarily (when doing my own tests) INSTALL_BASE => '$ENV{HOME}".'/usr', as a parameter to WriteMakefile() will install this module in user's own /home/user/usr dir which does not require admin rights.

        then insert an EXE_FILES => 'bin/myscript.pl' into Makefile.PL
        
        Is this the bin directory where 1.myscript.pl should end up?

        This is the path where each of the scripts you want installed system-wide (or user-dir-wide) LIVE NOW, in your module file structure. Their destination/installed dir is decided by the maker - you do not need to worry about that right now. Beware, I said EXE_FILES => ['bin/myscript.pl'], i.e. one or more scripts go into an array-ref (you need to enclose yours within square brackets). It's correct in your Makefile.PL but you cited it slightly wrong that's all.

        WARNING: Setting ABSTRACT via file 'lib/translate.pm' failed

        see What does this ABSTRACT warning from MakeMaker mean?

        My first question is whether I had to use require Exporter; our @ISA = qw(Exporter); our @EXPORT = qw( get_config get_trans get_from_lang get_to_lang reverse_trans);

        No you didn't have to but it is considered good practice not to "pollute the namespace of your module's users". Without exporting something, its access can be done via its full qualifier e.g. translate::get_from_lang();. You can not call that sub by using the shorter: get_from_lang(). Because it is not exported to the namespace of your module's users, unless you did so explicitly via the our @EXPORT mechanism. See also Selecting What to Export.

        Directory t/ contains all the test files run when you do make test. A few have already been created automatically by ExtUtils::MakeMaker and check for example if loading the module succeeds. In t/ you can add your own test files. For example there could be a test file which checks the functionality of get_config. I would call that test file t/01-get_config.t and could have something like this inside it:

        # t/01-get_config.t use strict; use warnings; use lib 'blib/lib'; use Test::More; use translate; my $num_tests = 0; my $ini_path = qw( /home/bob/Documents/html_template_data/3.values.ini + ); my $sub_hash = "google"; my $key = get_config($ini_path, $sub_hash); ok(defined $key, "get_config() : key defined"); $num_tests++; ok($key eq 'blahblah', "get_config() : key has correct value"); $num_t +ests++; # END done_testing($num_tests);

        After a user downloads your module, they should make test prior to installing it in order to make sure that the module works fine on their system (as opposed to working fine on author's system). So you must include as many test files as necessary to cover every aspect of your module's functionality. Perhaps as a minimum you should test the functionality of all your functions (exported/public or private). The more the better but not necessarily. Test files also help you to make sure that it works after you make a small change here or there: make a change, then run the tests. does it work? then your change *seems* not to have broken something. *seems*: always in relation to how well and comprehensive your test files are.

        Also, your module accesses a remote website. Testing this on a user's machine may not be a good idea, not without their permission perhaps. It will also fail without network access. I do not know what's considered a good practice in this situation.

        Directory xt/ should contain all the test files meant to be for author's use only. That is, the module user should not be concerned with running those. Only the author would find running them useful. You may have no author tests at all.

        There are many approaches and opinions about Testing. Perhaps you will find this useful I am most likely to install a new module from CPAN if:.

        Use git (github or your own server) to host your code for collaboration and as a version control system, i.e. to register incrementally your changes to your code so that you can rollback at any time.

        Disclaimer: please note that my knowledge of the above is at most average and seriously lacking commercial experience. It has been gained from doing my own projects, without peer-review from colleagues or supervisors as others here working for companies do every day. I am saying this not because of you doing something wrong on my advice (@&%^% that) but because there are battle-hardened veteran monks who are real experts and i think you should ask them too, or they should intervene if i am dispensing wrong or rubbish advice.

        bw, bliako