This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
In Perl, how can I check from which module a given function was imported?
Hi guys!
I am using my weekend time to comb through our web app to get a better understanding of it. It uses numerous modules whose functions get pulled into it and my question is this.. how can I determine the module where a function originates?
Reason I ask is because I am using print STDERR lines sprinkled here and there to understand the way data moves around (it has demystified things greatly).. here's an example....
($file_data,$count) = lookup_files($customer,$site,'','0',$d);
What I'm not sure of is where lookup_files() is originating from. What I'd like to see is this....
($file_data,$count) = lookup_files($customer,$site,'','0',$d);
print STDERR "lookup_files originates here " . <CODE TO SHOW ME WHERE lookup_files IS DEFINED>;
Any advice on where to begin would be greatly appreciated. The webapp uses tons of use modules and instead of selectively importing only what's needed, each use seems to bring all functions in.
I know my terminology might be incorrect when referring to "method", "parent" and so on in regards to Perl. If anyone would like to correct me on it that would be appreciated too. I am at best a beginner with this stuff. Janie
Take a look at the core module Devel::Peek
http://perldoc.perl.org/Devel/Peek.html#A-reference-to-a-subroutine
The output of that module's functions will tell you where a subroutine comes from
One fairly easy way is to load Carp::Always. If it’s a web app, you’ll need to put it in the code. For a command line you can just perl -MCarp::Always ...
Related
I have been "Dev Neutered" for a long time now and know enough powershell but not enough to solve this problem...
my kids have asked if I can write a script that returns the date of an event in a game and that game has an interface DLL that has the commands but I don't know what it is called or what is properties are.
So I was wondering if I can get some help on this. Basically I want to get a list of methods I can call and what the parameters required and what the results returned would be.
a Sample Powershell would be awesome! the DLL in question can be found at "https://7dtd.illy.bz/wiki/Server%20fixes"
thanks a ton!!
you can use these applications ( both free)
ILSpy: https://apps.microsoft.com/store/detail/ilspy/9MXFBKFVSQ13
dotPeek: https://www.jetbrains.com/decompiler/
I often work on a huge, not-very-well-documented, object-oriented Perl repo at my place of employment. While maintaining the code, I frequently need to trace things that are inherited from other classes so that I can understand what they're doing. For example, I need to figure out what $self->mystery is and what it's doing:
package Foo::Bar;
use Moose;
use Method::Signatures;
use Foo::Bar::Element;
use Foo::Bar::Function;
use base qw (Baz::Foo::Bar);
method do_stuff ($some_arg) {
# mystery is not defined in Foo::Bar
my $mystery = $self->mystery;
$mystery->another_mystery($some_arg);
}
I usually find myself spending way too much time tracing through parent classes. So my question is, is there an easy way for me to figure out where $self->mystery comes from? Or in other words, I need to find where mystery is declared.
And by "easy way", I don't mean using ack or grep to string search through files. I'm hoping there's some sort of debugging module I can install and use which could help give me some insight.
Thank you.
Thanks to Standard Perl . . . the comes_from Method!
You don’t need to download any special tool or module this, let alone some giant IDE because your undocumented class structure has gotten too complicated for mere humans ever to understand without a hulking IDE.
Why not? Simple: Standard Perl contains everything you need to get the answer you’re looking for. The easy way to find out where something comes from is to use the very useful comes_from method:
$origin = $self->comes_from("mystery");
$secret_origin = $self->comes_from("another_mystery");
$birthplace = Some::Class->comes_from("method_name");
That will return the original name of the subroutine which that method would resolve to. As you see, comes_from works as both an object method and a class method, just like can and isa.
Note that when I say the name of the subroutine it resolves to, I mean where that subroutine was originally created, back before any importing or inheritance. For example, this code:
use v5.10.1;
use Path::Router;
my($what, $method) = qw(Path::Router dump);
say "$what->$method is really ", $what->comes_from($method);
prints out:
Path::Router->dump is really Moose::Object::dump
Similar calls would also reveal things like:
Net::SMTP->mail is really Net::SMTP::mail
Net::SMTP->status is really Net::Cmd::status
Net::SMTP->error is really IO::Handle::error
It works just fine on plain ole subroutines, too:
SQL::Translator::Parser::Storable->normalize_name
is really SQL::Translator::Utils::normalize_name
The lovely comes_from method isn’t quite built in though it requires nothing outside of Standard Perl. To make it accessible to you and all your classes and objects and more, just add this bit of code somewhere — anywhere you please really :)
sub UNIVERSAL::comes_from($$) {
require B;
my($invocant, $invoke) = #_;
my $coderef = $invocant->can($invoke) || return;
my $cv = B::svref_2object($coderef);
return unless $cv->isa("B::CV");
my $gv = $cv->GV;
return if $gv->isa("B::SPECIAL");
my $subname = $gv->NAME;
my $packname = $gv->STASH->NAME;
return $packname . "::" . $subname;
}
By declaring that as a UNIVERSAL sub, now everybody who’s anybody gets to play with it, just like they do with can and isa. Enjoy!
Are you sure you don't want an IDE? It seems to be what you are asking about. Padre, Eclipse EPIC, Emacs , and vim and many other editors offer some variation on the features you mention - probably simpler than you seem to want. If you have big project to navigate ctags can help - it's usually easy to integrate into an editor and you are allowed to hack on your configuration file (with regexes BTW) to get it to recognize bits of a complicated set of source files.
There is a related PERL FAQ entry about IDEs and a SO question: What's a good development environment for Perl?. There are also a host of CPAN modules you will want to use when developing that let you look into your code programmatically:
Devel::Kit
Devel::Peek
SUPER
Devel::Trepan
MooseX::amine / mex
...
You can see an example of a script that looks for methods in classes in the SO node: Get all methods and/or properties in a given Perl class or module.
You might be able to get tools like these to help you hop around in your source in a way you find useful from a shell or from inside the debugger. Trepan has a good short summary of debugging tools as part of its documentation. Generally though you can be very productive combining Data::Dumper the B:: modules (B::Xref , B::Deparse, etc., etc.) with the debugger and ack.
I was wondering if anyone knew if it is possible to have MATLAB type a string for you, as if the user had typed it on the keyboard. I believe it can be done using a shell script or an applescript, but I was wondering if Matlab had a native implementation.
I have tried searching around for it, but have not had any luck. It is not super necessary, but I am just super lazy and want to write a script that will automatically enter information into an application after MATLAB has calculated stuff.
If you know of another simple way of doing this, let me know as well. Thanks a lot!
EDIT:
Adding some code that I used in response to an answer below, using the Java Robot Class
function robotType(text)
import java.awt.Robot;
import java.awt.event.*;
SimKey=Robot;
for i = 1:length(text)
if strcmp(text(i),upper(text(i))) == 0 || all(ismember(text(i),'0123456789')) == 1
eval(['SimKey.keyPress(KeyEvent.VK_',upper(text(i)),')'])
eval(['SimKey.keyRelease(KeyEvent.VK_',upper(text(i)),')'])
else
SimKey.keyPress(KeyEvent.VK_SHIFT);
eval(['SimKey.keyPress(KeyEvent.VK_',upper(text(i)),')'])
eval(['SimKey.keyRelease(KeyEvent.VK_',upper(text(i)),')'])
SimKey.keyRelease(KeyEvent.VK_SHIFT);
end
end
end
Warning, code may not be the best, but hey it was written in like 5 minutes.
I ended up writing an applescript to do everything that I needed Matlab to do. Unfortunately this will not help the Windows people, but myself and the other people using the script are mac users, so it works for us.
I have however, edited my question above to include code that I used initially in Matlab to auto type things. Simply run command as robotType('SomeString') and it will type that string.
I do not believe it will hand spaces or random characters that well, or at all, but it is good enough for abc123. Sorry for no final solution on this.
I've been assigned to pick up a webapplication written in some old Perl Legacy code, get it working on our server to later extend it. The code was written 10 years ago by a solitary self-taught developer...
The code has weird stuff going on - they are not afraid to do lib-param.pl on line one, and later in the file do /lib-pl/lib-param.pl - which is offcourse a different file.
Including a.pl with methods b() and c() and later including d.pl with methods c() and e() seems to be quite popular too... Packages appear to be unknown, so you'll just find &c() somewhere in the code later.
Interesting questions:
Is there a tool that can draw relations between perl-files? Show a list of files used by each other file?
The same for MySQL databases and tables? Can it show which schema's/tables are used by which files?
Is there an IDE that knows which c() is called - the one in a.pl or the one in d.pl?
How would you start to try to understand the code?
I'm inclined to go through each file and refactor it, but am not allowed to do that - only the strict minimum to get the code working. (But since the code never uses strict, I don't know if I'm gonna...)
Not using strict is a mistake -- don't continue it. Move the stuff in d.pl to D.pm (or perhaps a better name alltogether), and if the code is procedural use Sub::Exporter to get those subs back into the calling package. strict is lexical, you can turn it on for just one package. Such as your new package D;. To find out which code is being called, use Devel::SimpleTrace.
perl -MDevel::SimpleTrace ./foo.pl
Now any warnings will be accompanied by a full back-log -- sprinkle warnings around the code and run it.
I think the MySQL question should be removed, from this. Schema Table mappings have nothing to do with perl, it seems an out of place distraction on this question.
I would write a utility to scan a complete list of all subs and which file they live in; then I would write a utility to give me a list of all function calls and which file they come from.
By the way - it is not terribly hard to write a fairly mindless static analysis tool to generate a call graph.
For many cases, in well-written code, that will be enough to help me out...
I am a newbie learning sml and the question I am given involves IO functions that I do not understand.
Here are the 2 questions that I really need help with to get me started, please provide me with code and some explanation, I will be able to use trial and error with the code given for the other questions.
Q2) readlist(filename) which reads a list of filenames (each of which were produced by listdir in (Q1) and combines them into one large list.
(reads from the text file in Q1 and then assigns the contents into 1 big list containing all the information)
Thing is, I only learned from the lecturer in school on the introduction section, there isn't even a system input or output example shown, not even the "use file" function is taught. if anyone that knows sml sees this, please help. Thanks to anyone who took the effort to help me.
Thanks for the reply, current I am using SMLNJ to try and do this. Basically, Q1 requires me to list the directory's files of the "directoryname" provided into a text file in "filename". The Q2 requires me to read from the "filename" text file and then place the contents into one large list.
BTW, if you people only kept seeing this post, please try and ask questions also. Currently i am stuck trying to read from the txt file and appending it to a list, I am able to do it for a single line but am now trying to do it for the whole file:
fun readlist(infile : string) =
let val ins = TextIO.openIn infile
fun listing() =
TextIO.inputLine ins;
in listing()
end;
TextIO.closeIn;
It is very hard for me to make out what questions you are trying to ask.
The functions you ask about are not part of the Standard Basis Library for ML. If you are supposed to write them, you are going to have a hard time without some kind of Posix module. You can tell your instructor I didn't care for this assignment.
Moscow ML contains a listDir function which is admirably simple:
- load "Mosml";
> val it = () : unit
- Mosml.listDir ".";
> val it = ["natural-semantics.djvu", "natural-semantics.pdf"] : string list
-
To get more help, please be a little clearer what you are asking.
EDIT: Since it's a homework question I shouldn't just give you the answer, but some useful functions includeopenDir, readDir, and closeDir from the OS.Filesys structure. These will tell you what's in the directory. Then to read and write files you'll want TextIO.
You'll find the Standard Basis Library documentation indispensible.
You sure i didn't teach u?
u owe me one chicken pie.