Unexpected behavior with CPAN_JSON - perl

Trying to use CPAN_JSON in the following way:
my $integer = 200;
JSON->new->allow_nonref->encode($integer);
and get the following error;
Can't locate object method "FLAGS" via package "B::IV"
Coming from:
https://metacpan.org/source/MAKAMAKA/JSON-2.90/lib/JSON/backportPP.pm#L408
Running perl 5.8, I thought B Core packages are always included. Any ideas why this is happening?
Edit:
perl -v | grep This
This is perl, v5.10.1
perl -MJSON::backportPP -le'print $JSON::backportPP::VERSION || $JSON::PP::VERSION'
2.27200
perl -mB -le'my $value = 1; my $b_obj = B::svref_2object(\$value); print $b_obj->FLAGS;'
266498

Related

Patch binary with "perl -pi -e" doesn't work as expected in mac os mojave

I want to patch a binary file with perl. The command doesn't work today, but in the past I used it a lot .
The command below doesn't work on Mac Os X:
perl -pi -e 's|\xA0\x37\x96\x30\xDE\x90|\xA7\x70\x92\x30\xD5\x9B|' /file.bin
If I use
perl -MO=Deparse -pi -e 's|\xA0\x37\x96\x30\xDE\x90|\xA7\x70\x92\x30\xD5\x9B|' /file.bin
the result is:
BEGIN { $^I = ""; }
LINE: while (defined($_ = <ARGV>)) {
s/\xA0\x37\x96\x30\xDE\x90/\247p\2220\325\233/;
}
continue {
die "-p destination: $!\n" unless print $_;
}
-e syntax OK
Why the replace section was modified like this?
I checked 1000 time the syntax is correct; why it doesn't work as expected?
It wasn't modified.
"\xA7\x70\x92\x30\xD5\x9B"
and
"\247p\2220\325\233"
are equivalent.
$ perl -e'CORE::say "\xA7\x70\x92\x30\xD5\x9B" eq "\247p\2220\325\233" ? "same" : "diff"'
same
2478 = A716
p's ASCII encoding is 7016
2228 = 9216
0's ASCII encoding is 3016
3258 = D516
2338 = 9B16

Use of uninitialized value $e2 in string eq & find: warning:

Hopefully you can help a scientist to decipher whats wrong with the code I'm trying to run to clean up some NGS results. The Perl file itself comes from https://github.com/mtokuyama/ERVmap, though I am posting the code below for reference. The other Perl files in the package work just fine and, while I have built a passing ability to use the linux terminal, Perl is a little beyond me.
The linux terminal I'm using is currently running: Ubuntu 16.04.6 LTS
This is the Perl code I'm trying to run using the following command line on linux as instructed by their GitHub page:
perl clean_htseq.pl ./ c c2 __
#!/usr/bin/env perl
#$Id: run_clean_htseq.pl,v 1.2 2015/03/02 17:24:35 yk336 Exp $
#
# create pbs file
#
use warnings;
use strict;
use File::Basename;
use POSIX;
my $dir = shift;
my $e1 = shift;
my $e2 = shift;
my $stop = shift;
die "$e1 eq $e2" if ($e1 eq $e2);
my $find = "find $dir -name \"*${e1}\"";
my $out = `$find`;
my #files = split(/\n/, $out);
for my $f (#files) {
my $o = $f;
$o =~ s/${e1}$/$e2/;
my $cmd = "./clean_htseq.pl $stop $f > $o";
print "$cmd\n";
system($cmd);
}
The first error that I had was that the _clean_htseq.pl_ wasn't found (line 30, already altered to solution) which i solved by adding the ./ in front of it and giving the software permission to use the script file.
My current issue with the code/command line is the following error:
Use of uninitialized value $e2 in string eq at ./clean_htseq.pl line 18.
find: warning: Unix filenames usually don't contain slashes (though pathnames do). That means that '-name ‘*./SRR7251667.c’' will probably evaluate to false all the time on this system. You might find the '-wholename' test more useful, or perhaps '-samefile'. Alternatively, if you are using GNU grep, you could use 'find ... -print0 | grep -FzZ ‘*./SRR7251667.c’'.
This has been tracked down to the "__" at the end of the command line, while i'm sure this is supposed to mean something to the script I removed it and resulted in the following error:
Use of uninitialized value $stop in concatenation (.) or string at clean_htseq.pl line 30.
./clean_htseq.pl ./SRR7251667.c > ./SRR7251667.c2
Use of uninitialized value $e1 in string eq at ./clean_htseq.pl line 18.
Use of uninitialized value $e2 in string eq at ./clean_htseq.pl line 18.
Use of uninitialized value $e1 in concatenation (.) or string at ./clean_htseq.pl line 18.
Use of uninitialized value $e2 in concatenation (.) or string at ./clean_htseq.pl line 18.
eq at ./clean_htseq.pl line 18.
An error occurs too when I remove the "." from "./" but it comes back with an error about not finding the _clean_htseq.pl_ file which is in the working directory.
Your problem seems to be here:
my $dir = shift;
my $e1 = shift;
my $e2 = shift;
my $stop = shift;
Outside of a subroutine, shift works on #ARGV—the array that holds the command line arguments. You shift four times, so you need four arguments:
perl clean_htseq.pl ./ c c2 __
You only seem to give it two, and $stop has no value (so you are giving it less than two):
./clean_htseq.pl $stop $f
You can't just remove arguments and hope things still work out. Likely you're going to have to look at the source to see what those things mean (which should motivate you as a scientist to use good variable names and document code—Best Practices for Scientific Computing).
A first step may be to set defaults. The defined-or operator does well here:
use v5.10;
my $dir = shift // 'default_dir';
my $e1 = shift // 'default_value';
my $e2 = shift // 'default_value';
my $stop = shift // 'default_value';
Or, you could just give up if there aren't enough arguments. An array in scalar context gives you the number of elements in the array (although it doesn't guarantee anything about their values):
die "Need four arguments!\n" unless #ARGV == 4;
There are various other improvements which would help this script, some of which I go through in the "Secure Programming Techniques" chapter in Mastering Perl. Taking unchecked user input and passing it to another program is generally not a good idea.

perl throws error "length() used on #array (did you mean "scalar(#array)"?) at /usr/lib64/perl5/IO/Compress/Zlib/Extra.pm line 198."

The vsphere perl sdk version 5.5 is installed on centos 7 64 bit machine
The following simpleclient.pl(https://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.perlsdk.pg.doc/viperl_modscripts.4.2.html#990705) script throws error "length() used on #array (did you mean "scalar(#array)"?) at /usr/lib64/perl5/IO/Compress/Zlib/Extra.pm line 198." on centos-7 64 bit machine.
root#localhost vsphere_perl_exp]# cat simpleclient.pl
#!/usr/bin/perl
use strict;
use warnings;
use VMware::VIRuntime;
my %opts = (
entity => {
type => "=s",
variable => "VI_ENTITY",
help => "ManagedEntity type: HostSystem, etc",
required => 1
},
);
Opts::add_options(%opts);
Opts::parse();
Opts::validate();
Util::connect();
# Obtain all inventory objects of the specified type
my $entity_type = Opts::get_option('entity');
my $entity_views = Vim::find_entity_views(
view_type => $entity_type);
[root#localhost vsphere_perl_exp]# perl --version
This is perl 5, version 16, subversion 3 (v5.16.3) built for x86_64-linux-thread-multi
(with 25 registered patches, see perl -V for more detail)
Copyright 1987-2012, Larry Wall
Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.
Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http://www.perl.org/, the Perl Home Page.
Running perl with debug option stops at line 11,
[root#localhost vsphere_perl_exp]# perl -d ./simpleclient.pl --server 15.218.113.152 --username root --password 'secret' --entity HostSystem
Loading DB routines from perl5db.pl version 1.37
Editor support available.
Enter h or 'h h' for help, or 'man perldebug' for more help.
main::(./simpleclient.pl:6): my %opts = (
main::(./simpleclient.pl:7): entity => {
main::(./simpleclient.pl:8): type => "=s",
main::(./simpleclient.pl:9): variable => "VI_ENTITY",
main::(./simpleclient.pl:10): help => "ManagedEntity type: HostSystem, etc",
main::(./simpleclient.pl:11): required => 1
DB<1> main::(./simpleclient.pl:14): Opts::add_options(%opts);
DB<1>
I am newbie to perl, How to debug this script?
It's not an exception being thrown; it's a warning being printed.
IO::Compress::Zlib::Extra contained the code
for (my $ix = 0; $ix <= length(#$data) -1 ; $ix += 2)
It was fixed in 2.042 (Nov 17th, 2011)
for (my $ix = 0; $ix <= #$data -1 ; $ix += 2)
The change log references tickets 72329 and 72505, the first of which shows what effect the bug has. This instance of the bug is rather harmless save for the annoyance of seeing the message when using newer versions of Perl.
To upgrade:
sudo cpan IO::Compress::Zlib::Extra
To get the length of an array:
my $length = scalar #array;
To get the length of a string:
my $length = length("my string");
Hope this helps.

Adding sys/ioctl.ph to Perl headers

I need to use sys/ioctl.ph and it's not included in the perl version (5.12.3) shipped with my slackware distribution.
I did the following:
cd /usr/include
h2ph sys/ioctl.ph
cd /usr/lib64/perl5/site_perl/5.12.3/x86_64-linux-thread-multi/
mkdir sys
mv ioctl.ph sys
Now the perl interpreter doesn't complain about the sys/ioctl.ph, but this is the error I get:
Illegal declaration of subroutine Functions::ServerSocket::__INT16_C at /usr/lib64/perl5/site_perl/5.12.3/x86_64-linux-thread-multi/_h2ph_pre.ph line 164.
This is what there's in the file that causes the error at line 164:
unless (defined &__INT16_C(c)) { sub __INT16_C(c)() { &c } }
I don't know where to start. Functions::ServerSocket is one of my module, but I don't have any function like that in my file.
The __INT16_C macro on your platform is probably simple, e.g.,
#define __INT16_C(c) c
Replace the code on line 164 with
eval 'sub __INT16_C {
my($c) = #_;
eval q($c);
}' unless defined (&__INT16_C);
which is what other versions of h2ph generate.

Error in perl: Using a hash as a reference is deprecated

sub function{
my $storedata=shift;
my $storenameandaddress=$storedata->{$storeid}->{name}
."_".$storedata->{$storeid}->{location}->{address}
."_".$storedata->{$storeid}->{location}->{city}
."_".$storedata->{$storeid}->{location}->{state}
."_".$storedata->{$storeid}->{location}{country};}
My codes are shown above. and it gives me error message:
Using a hash as a reference is deprecated at main.pl line 141.
However, the function is still runable. And all the rests seem fine. So what is this error talking about? And how should I fix it? Thanks.
The code you posted does not give that warning. Code of the form
%foo->{bar}
gives that warning. It gives that warning because it functions as
$foo->{bar}
even though it's not supposed to.
$ perl -wE'my %h = ( foo => 123 ); say %h->{foo};'
Using a hash as a reference is deprecated at -e line 1.
123
$ perl -Mdiagnostics -wE'my %h = ( foo => 123 ); say %h->{foo};'
Using a hash as a reference is deprecated at -e line 1 (#1)
(D deprecated) You tried to use a hash as a reference, as in
%foo->{"bar"} or %$ref->{"hello"}. Versions of perl <= 5.6.1
used to allow this syntax, but shouldn't have. It is now deprecated, and will
be removed in a future version.
123
$ perl -wE'my %h = ( foo => 123 ); say $h->{foo};'
123