Hello everybody -
I have been using Padre for a month or two now and I really like it. In
particular, I really like the syntax checker since it has removed that
tedious get-it-to-compile step in my Perl coding. However, I have found a
few particularly annoying problems, one of which is a syntax checker problem
and the other of which is - I believe - a side-effect of the syntax
checker's behavior. I generally have two recommendations, which I will
summarize here:
1. The syntax checker needs to set the current working directory to the
script's directory.
2. Padre needs to work better with Inline's caching. Two potential hacks
to address this would be (a) piping the current buffer's content directly
into perl -c or (b) using a consistent temporary file name. A more fully
fledged solution would to have the Inline folks create a package variable
with the 'real' script's name that the syntax checker could set.
I have not come to either of these ideas without much deliberation. Below I
explain why I make these recommendations.
First, it appears that the syntax checker is executed from Padre's current
working directory rather than the directory of the current script. You
won't notice any problems as long as you only use modules in your system's
libraries, but if you try using modules in your current directory, you can
run into trouble. For example, a few layers below my home directory I have
a directory in which I'm working on an analysis script for my research. I
have written some worker modules that are in the 'My' subdirectory. My
script says to 'use My::Slices', which compiles fine when I run the script
on the command line from the same directory as the script, but the syntax
checker chokes on it. I've figured out some code that really explains the
environment in which the script is syntax checked:
--------------------%<--------------------
use Cwd qw/ abs_path /;
use warnings::register;
BEGIN {
foreach (@INC) {
warnings::warn ("$_ => " . abs_path($_));
}
}
--------------------%<--------------------
If you put those lines in any script that you're editing with Padre, you'll
get a list of directories in your @INC printed into your syntax checker
box. In particular it will tell you what it thinks of '.', i.e. the current
directory, if that's in your default @INC. I discovered that, in my case,
the 'current' directory had nothing to do with the script I was currently
working on.
I tried and tried but I could not figure out how to change the current
working directory of the syntax checker. Oddly, it was not my home
directory but was instead related to a file I had worked on. Clearly it can
be changed by the user, and quite possibly inadvertently, but I'm not sure
how.
I don't know Padre's code base (at all) so I don't know where to begin
looking to fix this issue. But to those who know the code better, I would
suggest that the syntax checker ought to temporarily chdir into the script's
directory before running the Perl compiler. File::chdir may be of some
assistance here, though I doubt that it's really necessary.
Second, the syntax checker works by storing the current state of the script
in a temporary file and then asking Perl to chew on it. When coupled with
some interesting behavior of Inline, this can give surprising and annoying
results.
First, the 'standard' method for invoking Inline does not give trouble
because under this usage, the Inlined code does not seem to get compiled by
Inline under the Perl compilation phase (which is in disagreement with
Inline's documentation). A toy example looks like this:
--------------------%<--------------------
use Inline C;
print "9 + 16 = ", add(9, 16), "\n";
__END__
__C__
int add(int x, int y) {
return x + y;
}
--------------------%<--------------------
However, we can change the way that we invoke Inline. Consider instead this
method of invocation:
--------------------%<--------------------
use Inline C => q{
int add(int x, int y) {
return x + y;
}
};
print "9 + 16 = ", add(9, 16), "\n";
--------------------%<--------------------
For reasons not entirely clear to me, Inline _will_ compile the code in
_this_ invocation when the syntax checker runs, but not under the _first_
invocation. This is nice because it tells you if you have any compiler
errors in your inlined code. However, it has a couple of problems when run
in combination with Padre's syntax checker.
Inline is fairly smart and only recompiles your Inlined code when it detects
a change, caching the results in one of many possible directories. If you
have no .Inline directories set up where it expects to find one, it will
create a directory called _Inline in your current working directory and
store the cached results there. This is the behavior that casual users of
Inline will get. In the standard Perl development style of edit-run-tweak,
this works just fine: you can change the Perl-side of your script, but
inline won't recompile the Inlined code unless it detects a change in that
code specifically.
Sensibly but unfortunately, Inline's change detection and caching involve
the script's name. In conjunction with Padre's use of temporary files for
the syntax checker, this means that Inline is forced to recompile your
Inlined code with every single syntax check, which makes my computer really
tired and fills _Inline with lots of often identical, .so files. In other
words, I could be editing a perl comment somewhere else in my script and
Inline will be slaving away with every keystroke - or however often the
syntax checker runs. I'm not complaining that the syntax checker compiles
the Inlined code. I think that's great, because it means that I can get
syntax checking for my Inlined code as well as my Perl code. The problem is
that Padre's current setup negates Inline's compiled cache unless the user
knows Inline well enough to specify Inline's NAME configuration setting. I
only learned to do that this morning, while investigating Inline. :)
One potential work-around here is to pipe the contents of the current window
directly to 'perl -c'. When Inline gets invoked by a script without a
filename, the resulting cache name is based (as best I can tell) on the
MD5-sum of the actual code fragment. If that doesn't change (because you're
editing Perl code, not Inlined code) it won't recompile. Alternately, you
could store the temporary file as something like 'myscript.pl~' or some
other common construction. The consistent filename would solve this
problematic interaction with Inline. Although this would result in
automatic backups, it would lead to problems when editing files over a
latent connection. Either way, the Inlined code will have to be recompiled
when the user runs their actual script, but as that's currently the case
anyway, I don't much care. A nice solution that solves all of this - and
would allow Padre to continue using its temporary file setup - would be if
we could somehow tell Inline to pretend that the currently -being-compiled
file has a name different than the (temporary) script at hand, perhaps
through shell variables or an Inline package global. But then we'd have to
talk to the Inline people and I figured I would keep this discussion to one
developers list for now. :)
A second and very subtle side effect of Padre's syntax checker and its
interaction with Inline relates to the current working directory. When
Inline creates its code that it compiles, it does so in a directory called
_Inline in your current working directory unless you've set up some other
directory for it to use. Since the syntax checker's current working
directory is not necessarily the directory of the script, as I have already
discussed, this means that casual users of Inline will have _Inline
directories littered throughout their home directory tree, filled with a
myriad of .so files that have been cached but which will never be used
again. Aside from the fact that this is annoying, it's also a waste of HD
space. This is a second reason why the syntax checker should switch the
current working directory to the script's directory.
Those are my thoughts. The change for the current working directory should
be a quick fix and I might have changed it by now myself if I knew the code
at all, but I don't. As for the Inline caching, I think the best solution
would be to coordinate with the Inline folks to have them query a package
global called $Inline::SCRIPT_NAME_MASQUERADE_AS or something like that.
David
_______________________________________________
Padre-dev mailing list
[email protected]
http://mail.perlide.org/mailman/listinfo/padre-dev