ExifTool Forum

ExifTool => Newbies => Topic started by: Luuk2005 on November 24, 2020, 01:09:24 AM

Title: How to learn the perl with -p ?
Post by: Luuk2005 on November 24, 2020, 01:09:24 AM
Greeting to any of the perl experts!
Im not allowed to install the perl installation, so many times Im trying to learn with the expiraments inside of -p "${Tag; $_ = here;}" but often the exiftool presents to the screen like: Warning: Undefined subroutine Image::ExifTool::Expirament. In the cmd.exe, we just type 'help' to list supported commands, but this also presents 'undefined subroutine'

Many things like s///, rand(), int() conduct like the explanations, but others like rand_date() always present 'undefined subroutine'.. So how to make them defined? Does the exiftool need Path::To::rand_date() to first make them defined?? How to get the list/path of allowed subroutines/functions/methods/etc for the expiraments ?

Also if anybody knows, can we set global variable to survive after each filename is conducted ?
And is there any way to use $Tag2 inside of -p ${Tag1; $_ = here;} ?
Many thanks in advance.

Edit: Im thinking global variable is not to be possible with -p, because -p restarts each filename, but maybe there is another way?
Title: Re: How to learn the perl with -p ?
Post by: Phil Harvey on November 24, 2020, 07:30:17 AM
Quote from: Luuk2005 on November 24, 2020, 01:09:24 AM
others like rand_date() always present 'undefined subroutine'..

Where is rand_date() defined?  Here is a list of built-in Perl functions that you can use (https://perldoc.perl.org/functions).

QuoteAlso if anybody knows, can we set global variable to survive after each filename is conducted ?

You could create a variable like $Image::ExifTool::myVariable if you want.

QuoteAnd is there any way to use $Tag2 inside of -p ${Tag1; $_ = here;} ?

$self->GetValue('TAG2')

- Phil
Title: Re: How to learn the perl with -p ?
Post by: StarGeek on November 24, 2020, 10:56:41 AM
It looks like rand_date() is part of Data::Random (https://metacpan.org/pod/Data::Random).

Quote from: Luuk2005 on November 24, 2020, 01:09:24 AM
So how to make them defined? Does the exiftool need Path::To::rand_date() to first make them defined?? How to get the list/path of allowed subroutines/functions/methods/etc for the expiraments ?

If it's a pure Perl module, you could download the raw files and put them in a properly structured lib like directory.  Then you could put a line at the start of your .exiftool_config file to point to that directory.  For example, with my Strawberry Perl installation, I have this line at the top of my config file which allows me to add any pure Perl CPAN module I install to my user-defined tags
BEGIN{ push @INC, 'C:\Strawberry\perl\lib'; push @INC, 'C:\Strawberry\perl\site\lib'; push @INC, 'C:\Strawberry\perl\vendor\lib'}
You can then add access to those mods, even on the command line by "using" them, e.g. use Data::Dumper;

But some Perl modules, such as the SSL part of LWP::Simple (required to do an https:// request), include DLLs which won't load with the PAR packer used to create the Windows executable.
Title: Re: How to learn the perl with -p ?
Post by: Luuk2005 on November 25, 2020, 06:58:22 PM
Many, many thanks for all the replies, and also for the links to study. Im learned much already from the reading! I was believing that ALL subroutines are 'built-in', but sometimes we needed Path::subroutine, because the exiftool prefers Image::ExifTool. Now Im understanding that modules is more like add-ons, to gain more customized subroutines/variables?

So I downloaded from http://metacpan.org/pod/Data::Random, the .tar.gz and extract to C:\Data-Random-0.13\. The paths inside are: \t\, \share\, and \lib\Data\Random\ with the module settled at \lib\Data\Random.pm.  Then I create 'C:\Windows\.exiftool_config' with Line1: BEGIN{push @INC,'C:\Data-Random-0.13\lib'}

Im already tested to know exiftool reads the config, but Data::Random::rand_date() still presents 'undefined subroutine'. So I copy Random.pm to \lib\Random.pm and \Data\Random\Random.pm, but this also not helps with the definition path. So then I use: BEGIN{push @INC,'C:\Data-Random-0.13\lib';push @INC,'C:\Data-Random-0.13\lib\Data';push @INC,'C:\Data-Random-0.13\lib\Data\Random'} trying both double-quotes and single-quotes.

I also did experiments with different paths like Data::rand_date() or Random::rand_date() but this subroutine remains undefined. I become so frustrated to make my own ${Tag;Expressions} to invent the random dates, but its very long and tedious for the typing. Its much easier if I can just type rand_date() but Im thinking maybe it requires the perl installation? or maybe this Random.pm is not pure?

This first time using the .exiftool_config, so hoping maybe there can be just simple mistakes to fix. Im also studied user-defined tags, so to create $RandDate instead, but this also does not work, even after much studying the syntax. Always -p "$RandDate" presents the warning: 'RandDate' not defined and Im not even using -fast4. This my .exiftool_config ...
BEGIN{push @INC,"C:\Data-Random-0.13\lib"; push @INC,"C:\Data-Random-0.13\lib\Data"; push @INC,"C:\Data-Random-0.13\lib\Data\Random"}
%Image::ExifTool::UserDefined = (
  "Image::ExifTool::Composite" => { MyModel => {Require => {0 => "Exif:Model"},      ValueConv => '$val[0]' },
                                     MyMake => {Require => {0 => "Exif:Make"},       ValueConv => '$val[0]' },
##Comments                                                                                                1972-2021       :       1-12month   :       1-31day            0-23hr     :      0-59min    :      0-59sec  ;             Fix 30-day months             ;            Feb3*-->Feb29            ;                         NonLeapYear:Feb29-->Feb28                             ;         Pad for eyesight     ;   
                                   RandDate => {Require => {0 => "System:Filename"}, ValueConv => '$_=int(1972+rand(50)).":".int(1+rand(12)).":".int(1+rand(31))." ".int(rand(24)).":".int(rand(60)).":".int(rand(60)); $_=~s/^(\d+:(?:[469]|11):)31(.*)/${1}30$2/; $_=~s/^(\d+:2:)(?:3\d)(.*)/${1}29$2/; $_=~s/^(..(?:7[^26]|8[^048]|9[^26]|0[^048]|1[^26]|2[^048]):2:)29(.*)/${1}28$2/; $_=~s/(?<!\d)(\d)(?!\d)/0$1/g; $_' },

                                  }
);


Im thinking maybe the best solution is covertly install the perl, without being reported as installation.
If nothing else, I would like to get $RandDate conducting properly, I know its to be possible because the command line version does always succeed...
exiftool -q -r -fast4 -p "${Filename; $_=int(1972+rand(50)).':'.int(1+rand(12)).':'.int(1+rand(31)).' '.int(rand(24)).':'.int(rand(60)).':'.int(rand(60)); s/^(\d+:(?:[469]|11):)31(.*)/${1}30$2/; s/^(\d+:2:)(?:3\d)(.*)/${1}29$2/; s/^(..(?:7[^26]|8[^048]|9[^26]|0[^048]|1[^26]|2[^048]):2:)29(.*)/${1}28$2/; s/(?<!\d)(\d)(?!\d)/0$1/g}" .|sort

Many thanks again for the great support!
Title: Re: How to learn the perl with -p ?
Post by: StarGeek on November 25, 2020, 08:34:18 PM
I believe all you should need is the path to the lib directory.
BEGIN{push @INC,"C:\Data-Random-0.13\lib";}

You still need to let Perl know to load the module and make it clear that the rand_date() is not an Image::ExifTool function.  These work for me once I cpan'ed Data::Random.  You still need the above instruction in your .exiftool_config
C:\>exiftool -p "${Filename;use Data::Random qw(rand_date);$_=rand_date()}" y:\!temp\Test4.jpg
2020-12-23

C:\>exiftool -p "${Filename;use Data::Random;$_=Data::Random::rand_date()}" y:\!temp\Test4.jpg
2021-04-28


The first loads only the rand_date() function.  The second makes it clear that the function is not part of Image::ExifTool, otherwise I get a Warning: Undefined subroutine Image::ExifTool::rand_date called for 'Filename'
Title: Re: How to learn the perl with -p ?
Post by: Luuk2005 on November 26, 2020, 09:30:58 AM
A million thanks for your reply! This was enough to finally present the warning to inform me the error.
Dont ask me why, but inside double-quotes the config demands \\ for \, so I just use single-quotes like you first posted, and now all works as to be expected!

At the time, Im not knowing about use Module::Path, so in frustration changed your single-quotes to double-quotes. Then even more frustration, so I copied the .pm everywhere and adding paths to see if that helps. I had a feeling this was to be simple mistake, I do same thing using Filename versus FileName to fix the $RandDate.

Many thanks for the link also, it lets me study the gmtime() to also invent another method ...exiftool -fast4 -p "${filename; my($s,$mi,$h,$d,$mo,$y)=gmtime(63072000+int(rand(1546387200))); $_=join(':',1900+$y,1+$mo,$d,$h,$mi,$s); s/(?<!\d)(\d)(?!\d)/0$1/g; s/(.{10}):/$1 /}" .
Now Im making it in the config to discover which method is to be fastest, but also reliable. Its unfortunate that CompositeTags like $RandDate can only use -fast3.
Both of your commands using the Data::Random module do fully support using -fast4, so Im thinking they win the race.
Many thanks again, this forum has best support on the internet!
Title: Re: How to learn the perl with -p ?
Post by: Phil Harvey on November 26, 2020, 09:44:22 AM
Quote from: Luuk2005 on November 26, 2020, 09:30:58 AM
Its unfortunate that CompositeTags like $RandDate can only use -fast3.

I'll change this in ExifTool 12.11 so Composite tags will be generated when -fast4 is used.

- Phil