Hi Ben,
I start from the bottom.
On May 22, 4:53 pm, Ben Morrow <
b...@morrow.me.uk> wrote:
> What is your actual problem? You appear to be thrashing about, trying a
> whole lot of things you don't really understand and making a horrible
> mess, but you haven't explained what you're trying to do and how it
> isn't working.
Sorry. I find this a bit unfair, but I asked for it.
It is absolutely correct that I touch things I don't fully understand.
On another hand, I believe that the guy who wrote this package did
understand what he did.
This doesn't make the result perfect.
What I try to do, I explained in my introduction: the context is to
improve an existing module, which has users, hence respecting its
backwards compatibility.
Now there are precise issues:
> > In particular, somebody brought to my attention the fact that errors
> > in sub-modules which Wrapper loads, are ignored.
Apart for that, this module works satisfactorily and provides a useful
service.
What service? It doesn't really make sense that I copy the doc which I
referred to, on CPAN.
This sets up an infrastructure for developing wrappers around a
proprietary tool, extending or modifying this one's behavior.
I develop myself one such wrapper.
> > local $^W = 0; # in case a function is redefined
> > eval {
> > local @INC = ($dir); # make %INC come out right
> What is $dir?
This is enclosed in a:
for my $dir (@INC) { ... }
loop. Wrapper modules will be searched under ClearCase/Wrapper
hierarchies below each such $dir.
Setting @INC to ($dir) restricts the number of visible packages.
Most commonly, the wrapper modules will be found under site_perl,
whereas strict or File::Find are located under lib.
Hence this restriction will prevent accessing many useful modules
specifed with 'use'.
> > eval "require $pkg";
> > };
> > warn $@, next if $@;
>
> > I restored the warnings, excepting 'redefine'.
> How did you do that? If you used 'warnings', it won't do what you
> expect. The reason for using $^W is that it propagates into required
> modules; 'warnings' does not.
Right. Thanks. I indeeed used 'no warnings q(redefine)'.
Redefining functions is not something generally recommendable.
It has only come necessary for backwards compatibility reasons, while
adding a top level loop to the wrapper infrastructure, hence requiring
to catch existing 'exit' and 'exec' calls.
It may well stay limited to one level.
> OTOH, $^W will only silence warnings in
> code not under 'warnings', so that's not terribly useful either.
> If you want to do this right, you either need to find a way to avoid
> redefining functions, or you need to set up a local __WARN__ handler
> which filters out the 'redefined' warnings.
I had a look at that and couldn't quite figure out how to do it.
But let's leave it for now.
> > I moved the 'warn $@' inside the eval block, right after the require.
> > This gave me errors for all the modules used.
> What errors?
Cannot find File::Find was one.
Sorry, I am home now, without access to my logs or the environment.
> > I removed the @INC restriction, and got to the next problem.
> ...so, @INC = $dir was completely wrong, and nothing was getting loaded
> at all, but you weren't seeing errors because you threw them away? OK.
As far as I can tell, no.
It must have done something useful despite the hidden errors.
Or I am understanding even less than you think.
What does 'require' do in presence of errors?
Somehow it must have skipped them in some way...
> > Now I got into %{"${pkg}::"} not only the local symbols, but also all
> > imported functions (e.g. 'find' from File::Find).
> > The problem is that I need this information (the local symbols) for
> > the remaining part.
> Sub::Identify will tell you where a sub comes from.
Thanks... Interesting.
> Be careful about grubbing around in the symbol tables: there can be
> things in there you may not expect. For instance, a constant created
> with 'constant' is represented as a scalar ref in the symbol table,
> where you would expect a glob to be. If you look up the glob by name
> perl will transform it into a real glob for you, but if you try to
> follow the ref from the stash you will find it isn't what you expect.
OK.
> > Most of the symbols are indeed found in the autosplit.ix file which is
> > also accessed, but not all:
> > (first) some functions might have been excluded from the
> > autosplitting, and (second) functions may have been aliased to shorter
> > names, not matching any new *.al file (listed in autosplit.ix).
>
> > My next move was to try to (optionally) 'require' twice, first in an
> > open verbose mode, then as previously.
>
> What did you think that would do?
I thought the first pass would populate the symbol table with
everything useful plus extra symbols I didn't want. It would give me
the useful errors and warnings I was lacking, without spurious extra
ones which obviously didn't affect the behavior.
I would throw away the whole result and the second pass would do as it
had always done, and whatever this is.
Now, as told, I noticed that I failed to 'throw away the whole
result', and that the first pass affected the second.
> > In the meanwhile, I restored %{"${pkg}::"} to its initial state.
> Be *even* *more* careful about changing the stashes directly. This is an
> area where there are still (probably) bugs in perl: here be segfaults.
OK. This was my attempt to clean up the result of the first phase.
Naive maybe.
> > This led to the next error: 'use vars', in the sub-modules, was
> > evaluated only once, the first time.
> If you require the same file twice, without clearing the %INC entry, the
> second time will do nothing. This is (pretty-much) the whole point of
> require.
OK. I could clean up %INC. Thanks.
Er... Was that a recommendation?
> > Deep in what looks as a dead end, I ask for critique and help
I got both.
In summary, you offer me two venues. Either:
- use Sub::Identify to skip some entries in %{"${pkg}::"}, without
needing to touch it after the single pass needed.
- cleaning %INC in addition to what I already did.
Clearly the first one looks preferable, especially as I still don't
understand how the 'use vars' were affected (and probably the 'use
constant' as well).
There obviously remains something unsettled about what actually
happens in the original code, with the require under a restricted
@INC, and throwing errors away.
I would be *very* surprised if nothing at all.
In fact, I don't know where else the modules could be loaded...
And, they are.
Thanks,
Marc
Marc
Thanks.