How to learn the perl with -p ?

Started by Luuk2005, November 24, 2020, 01:09:24 AM

Previous topic - Next topic

Luuk2005

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?
Windows8.1-64bit,  exiftool-v12.92(standalone),  sed-v4.0.7

Phil Harvey

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.

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
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

StarGeek

It looks like rand_date() is part of 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.
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Luuk2005

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!
Windows8.1-64bit,  exiftool-v12.92(standalone),  sed-v4.0.7

StarGeek

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'
"It didn't work" isn't helpful. What was the exact command used and the output.
Read FAQ #3 and use that cmd
Please use the Code button for exiftool output

Please include your OS/Exiftool version/filetype

Luuk2005

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!
Windows8.1-64bit,  exiftool-v12.92(standalone),  sed-v4.0.7

Phil Harvey

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
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux/PowerShell, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).