Re: Recover a path from a config file
by haukex (Archbishop) on Jun 06, 2016 at 10:51 UTC
|
Hi Chaoui05,
Because the $folder variable is declared with my, it exists only for the scope of the config file and is not accessible from the main script. One quick solution would be to replace the "my" with an "our" in the config file, as that declares the variable as a package ("global") variable, then add a declaration of "our $folder;" (or "use vars qw/$folder/;", but that's discouraged) before the line with do 'work.conf' (this is to satisfy strict), then the variable $folder will be accessible in the script, and then you can do:
use File::Spec::Functions qw/catfile/;
my $filename = catfile($folder, $config->{license});
Hope this helps, -- Hauke D
Edit: Minor updates to wording. | [reply] [d/l] [select] |
|
|
Global symbol "$folder" requires explicit package name at...line44
Thanks in advance !
*****Lost in translation****TIMTOWTOI****
| [reply] [d/l] |
Re: Recover a path from a config file
by Corion (Patriarch) on Jun 06, 2016 at 11:39 UTC
|
Personally, I would make $folder part of the config structure:
my $folder = 'some/where/else';
{
my $folder = 'E:\FOLDER\Test\WEB';
{
source_folder => $folder,
license => 'kit-licence.zip',
programs => [
#template society =>\%program_work
'VIKTOR DESCRIPTION PRODUCT' => {
name => 'VIKTOR ',
parameters => [
Count_id => '06 (
+Viktor)',
Birth_date => '1995-04-3
+0',
Marriage_date => '2014-05-26',
Divorce_date => '2015-03-30',
Activities_folder => $folder.
+'\VIKTOR\independent worker',
Activities_format => 'Enterpr
+ise Format (V35)',
Description_File_from => $folder.'\VI
+KTOR\FILE\description.xlm',
]
},
]
};
};
| [reply] [d/l] [select] |
|
|
Hello Corion. Thanks for reply
I thought about your approach but i cannot modify my config.file
So i have to do differently.
*****Lost in translation****TIMTOWTOI****
| [reply] |
|
|
Hi Chaoui05,
i cannot modify my config.file
With Perl you can ;-)
There are several other ways to solve this (maybe even PadWalker), and personally I think the following is a hack that's not very nice, but it works as long as your config file only contains one declaration of my $folder...
my $conf_str = do { open my $fh, '<', 'work.conf' or die $!;
local $/; <$fh> }; # slurp
( $conf_str =~ s/\bmy\s*\$folder\b/our \$folder/g )==1
or die q{Failed to match "my $folder" exactly once};
our $folder;
my $config = eval $conf_str;
Hope this helps, -- Hauke D | [reply] [d/l] [select] |
|
|
|
|
|
|
|
use strict;
use warnings;
use Data::Dumper;
my ($content);
{ open my $fh,'<','work.conf' or die $!;
local $/;
$content = <$fh>;
}
my $config = eval $content;
print Dumper(\$config);
But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)
| [reply] [d/l] [select] |
|
|
|
|
|
Re: Recover a path from a config file
by BrowserUk (Patriarch) on Jun 06, 2016 at 11:48 UTC
|
If you create the variable in the config as $::folder = 'E:\FOLDER\Test\WEB';, then it is available in the main program in the same way.
However, the bulk of the config will be inaccessible as it is declared as an anonymous hash with no name.
You could fix that with work.conf:
$::folder = 'E:\FOLDER\Test\WEB';
$::config = {
license => 'kit-licence.zip',
programs => [
#template society =>\%program_work
'VIKTOR DESCRIPTION PRODUCT' => {
name => 'VIKTOR ',
parameters => [
Count_id => '06 (
+Viktor)',
Birth_date => '1995-04-3
+0',
Marriage_date => '2014-05-26',
Divorce_date => '2015-03-30',
Activities_folder => $folder.
+'\VIKTOR\independent worker',
Activities_format => 'Enterpr
+ise Format (V35)',
Description_File_from => $folder.'\VI
+KTOR\FILE\description.xlm',
]
},
]
};
Main program: #! perl -slw
use strict;
use Data::Dump qw [ pp ];
do 'work.conf' or die $!;
print $::folder;
pp $::config;
Output: C:\test>junk
Name "main::folder" used only once: possible typo at C:\test\junk.pl l
+ine 7.
Name "main::config" used only once: possible typo at C:\test\junk.pl l
+ine 9.
E:\FOLDER\Test\WEB
{
license => "kit-licence.zip",
programs => [
"VIKTOR DESCRIPTION PRODUCT",
{
name => "VIKTOR ",
parameters => [
"Count_id",
"06 (Viktor)",
"Birth_date",
1995-04-30,
"Marriage_date",
2014-05-26,
"Divorce_date",
2015-03-30,
"Activities_folder",
"E:\\FOLDER\\Test\\WEB\\VIKTOR\\independent wo
+rker",
"Activities_format",
"Enterprise Format (V35)",
"Description_File_from",
"E:\\FOLDER\\Test\\WEB\\VIKTOR\\FILE\\descript
+ion.xlm",
],
},
],
}
Also $main::config & $main::folder would work. Or you could go the OO route and make work.conf a proper object.
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.
| [reply] [d/l] [select] |
|
|
Hello . Thanks for reply.
In fact, i just want to get my path + filename in my test.pl using perl, knowing i have to keep my config.file unchanged.
Thanks in advance !
*****Lost in translation****TIMTOWTOI****
| [reply] |
Re: Recover a path from a config file
by RonW (Parson) on Jun 06, 2016 at 19:27 UTC
|
Using do or eval to parse files like your work.conf is potentially very dangerous. Arbitrary Perl code can be inserted in files like that.
I have used Data::Undump with some success to more safely read data from files like your work.conf
However, since you are interested in only the values for $folder and license, you could extract those with regular expressions
(Untested)
use strict;
use warnings;
my $dir;
my $lic;
my $cfgf = 'work.conf';
open my $cfgh, '<', $cfgf or die "Can't open $cfgf: $!\n";
while (<$cfgh>)
{
if (/\$folder\s+=\s+'([^']+)'/)
$dir = $1;
next;
}
if (/license\s+=>\s+'([^']+)'/)
{
$lic = $dir . $1;
last;
}
}
print "Folder: $dir\nLicense: $lic\n";
| [reply] [d/l] [select] |
|
|
Hello ,
Thanks for your approach. It's a very interesting to use regex . I didn't think about that even if i have to learn more about them.
Concerning do i use, i have to employ that to read my file.
I didn't know it can be dangerous to use do or eval. The advantage of my conf.file is the format because it uses Perl.
*****Lost in translation****TIMTOWTOI****
| [reply] [d/l] [select] |
|
|
The advantage of my conf.file is the format because it uses Perl. Think of it like a perl program, because it is a perl program, use/require/do/eval, they all run perl programs like "perl" The assumptions/conventions are different, but its full perl interpreter, unrestrained
| [reply] |
|
|
Re: Recover a path from a config file
by anonymized user 468275 (Curate) on Jun 06, 2016 at 19:24 UTC
|
Strangely I didn't see this at the beginning of the evening, but after four glasses of wine, I suddenly thought of this and began to wonder why not only me but noone else thought of it yet. I do NOT claim it's subtle coding ;)
open my $ch, 'path to config file';
my $folder;
my $assignment = <$ch>;
close $ch;
chomp $assignment;
$assignment =~ s/^\s*my\s*//;
eval $assignment; # assigns to THIS scope!
| [reply] [d/l] |
|
|
| [reply] |
|
|
I don't want to get into that example in too much detail as it serves no proper purpose. However, I do have issues with it, for example the local $/ doesn't assign anything so doesn't do anything. Meanwhile I have been thinking what would a proper solution be and I keep getting back to the fact that this is not the best way write a config file. Better would be to have
{ folder => 'path',
in the following hash, instead of my $folder = 'path';
In any case, unless the config file is used to load all configuration data rather than pick just one item, then it is being misused as well as ill-conceived. There are two types of config file. The language portable one that is just a list of identifiers followed by their values and the "normal" perl way: a class-qualified symbol and a hash assigned to it, which is intended to be loaded in easily enough using just one "require" statement.
Unfortunately, the OP seems to be suffering from an organisation culture that stubbornly resists change even to fix bad implementations. In the wider Perl community we know who they are by reputation and simply avoid working there!
| [reply] [d/l] [select] |
|
|
|
|
|
|
|
|
|
| [reply] |
Re: Recover a path from a config file
by Chaoui05 (Scribe) on Jun 06, 2016 at 15:51 UTC
|
I did that now and it works:
In my folder, in config.file
$::folder = 'E:\FOLDER\Test\WEB';
And in my test.file :
use File::Spec::Functions qw/catfile/;
my $filename = catfile($::folder, $config->{licence});
And it works fine.
Thanks all
PS: I have now my config.file with thoses little changes, at the beginning of this one :
my $folder = 'E:\FOLDER\Test\WEB';
{
license => [ 'kit-licence.zip',
'kit-work.zip'
],
programs => [..
I have this simple question. How can i do if i want to get first licence or the second doing that :
use File::Spec::Functions qw/catfile/;
my $filename = catfile($::folder, $config->{licence});
Thanks
*****Lost in translation****TIMTOWTOI****
| [reply] [d/l] [select] |
|
|
use strict;
use warnings;
#use Data::Dumper;
my ($content);
{ open my $fh,'<','work.conf' or die $!;
local $/;
$content = <$fh>;
}
my $config = eval $content;
#print Dumper(\$config);
print 'Licences: ' . join ',', @{$config->{licence}};
Update: to look at the first and second specifically, try the following.
printf "First licence: %s\n", ${$config->{licence}}[0];
printf "Second licence: %s\n", ${$config->{licence}}[1];
Updated again: if the contents of the licence tag could be either a single value or a list of values, you will need to use the ref command to tell the difference.
use File::Spec::Functions qw/catfile/;
...
if (ref($config->{licence}) eq 'ARRAY') {
foreach my $lfile (@{$config->{licence}}) {
print catfile($::folder,$lfile)
}
} else {
print catfile($::folder,$config->{licence})
}
But God demonstrates His own love toward us, in that while we were yet sinners, Christ died for us. Romans 5:8 (NASB)
| [reply] [d/l] [select] |
|
|
| [reply] |
Re: Recover a path from a config file
by Chaoui05 (Scribe) on Jun 06, 2016 at 13:27 UTC
|
Maybe i didn't ask clear enough my question. I don't want to recover all my config.file. I can do it. I just want to recover path "my $folder" . And add just after licence filename.
I'am doing some tests and i would like to get from my config.file this path using Perl.
And use ,after that, this file to do my tests. Knowing i have to keep my config.file almost identical. For example, i can change "my" to "our" to get a global variable cause it's a very small change.
Global variable seems to be a good approach but i have above issue as i told before.
HTH
Many thanks again !!
*****Lost in translation****TIMTOWTOI****Almost a monk***
| [reply] |
|
|
I am confused about this "I can change some stuff, but not much stuff" requirement?
The code from BrowserUk works fine for me. To eliminate the "only used once" warnings, just declare $folder in main:: as an "our" variable. An "our" variable gets into the global symbol table and can be accessed by anybody with the full name without any import/export adieu. Here is a modified main program...
#! perl -slw
use strict;
use Data::Dump qw [ pp ];
our $folder; #to prevent "only used once" warnings
our $config;
do 'work.conf' or die $!;
print $folder; # $folder is declared above, here in $main
# not in file work.conf
# since we are in main, don't need "full name"
pp $::config; #can use full name here, but not necessary
work.conf as posted by browserUk:
$::folder = 'E:\FOLDER\Test\WEB';
$::config = {
license => 'kit-licence.zip',
programs => [
#template society =>\%program_work
'VIKTOR DESCRIPTION PRODUCT' => {
name => 'VIKTOR ',
parameters => [
Count_id => '06 (Viktor)',
Birth_date => '1995-04-30',
Marriage_date => '2014-05-26',
Divorce_date => '2015-03-30',
Activities_folder => $folder.'\VIKTOR\i
+ndependent worker',
Activities_format => 'Enterprise Format
+ (V35)',
Description_File_from => $folder.'\VIKTOR\F
+ILE\description.xlm',
]
},
]
};
works fine. Why isn't this good enough?
As an update, This back slash stuff for file names under Windows is not required. Use the forward slash. That is easier, more portable and completely allowed since I think at least Win98. The modern Window's command line is NOT DOS. | [reply] [d/l] [select] |
|
|
| [reply] |
|
|
|
|
|
|
|
Hi Chaoui05,
For example, i can change "my" to "our" to get a global variable cause it's a very small change.
But earlier you said:
I meant i have to not modify my config.file. I have to keep it unchanged.
... so if you can edit your config file, and if by "above issue" you mean this, then have a look again at my post, I'm guessing you missed the our $folder; in your main script.
Hope this helps, -- Hauke D
| [reply] [d/l] |
|
|
Yes excuse me. I was too much affirmative. Much for me.
I can do some little changes , which do not lead to a significant impact on config.file structure. I meant.
In all cases, thanks again haukex. And yes i will review that .
*****Lost in translation****TIMTOWTOI****
| [reply] |
Re: Recover a path from a config file
by Chaoui05 (Scribe) on Jun 07, 2016 at 13:29 UTC
|
Hey monks !
I request your wisdom last time for this subjet. I would prefer to post it here than to edit it in a new post.
I would like to get value below :
name => 'VIKTOR ',
And i did that :
my $firstName = $config->{name};
And i tried following code too but it doesn't work too:
my $firstName = ${$config->{programs}}[0];
It doesn't work . I would like to understand. Did i forget something?
Thanks !!
*****Lost in translation****TIMTOWTOI****Scribe !yes!***
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
my $firstName = $config->{name};
I get the following output :
Use of uninitialized value $firstName in print atline 115.
And when i do that :
my $firstName = ${$config->{programs}}[1];
i get output below :
HASH(0x3e25178)
If i do :
my $firstName = ${$config->{programs}}[0];
i obtain in my output:
VIKTOR DESCRIPTION PRODUCT
*****Lost in translation****TIMTOWTOI****
| [reply] [d/l] [select] |
|
|
|
|