Perl changing the current package? - perl

Without using a source-filter, is there a way to change the current running package? I'm trying to accomplish the same thing oose.pm does, and I'm wondering if I can drop my users in a non-main package.

I think you'll be able to do that by changing PL_curstash and PL_curstname on the C level.
PL_curstash = gv_stashpvs("Some::Package", GV_ADD);
sv_setpvs(PL_curstname, "Some::Package");
PL_curstash is the stash of the current package during compilation, PL_curstname is its name.
Update:
I've found this problem kind of interesting and implemented the solution as Devel::ChangePackage. Turns out what I initially suggested just works. You can get it either from http://github.com/rafl/devel-changepackage, or from a CPAN mirror near you once they have updated.

Related

why is it possible to set $GLOBALS['TBE_STYLES']['logo'] in typo3conf/extTables.php, but not in typo3conf/AdditionalConfiguration.php?

just out of curiosity:
As you all might or might know, it is possible to set a custom BE logo with $GLOBALS['TBE_STYLES']['logo'] = '../fileadmin/mylogo.png'; in typo3conf/extTables.php.
This behavior is working since old v4.x times.
But I just read that extTables will be deprecated in v8.x.
I tried to find a simple solution to this (one that keeps that one-line simplicity and does NOT require me to create&install an extension!)
I moved this line to typo3conf/AdditionalConfiguration.php,
but it does not work from there.
Why?
What would be necessary to make this line work within typo3conf/AdditionalConfiguration.php ?
In TYPO3 8.x you'll be able to change a backend logo via EXT:backend, so you should stick to that approach. Read more in release notes.
UPDATE.
To answer your question, why TBE_STYLES defined in AdditionalConfiguration are ignored: take a look at unsetReservedGlobalVariables() method from \TYPO3\CMS\Core\Core\Bootstrap class. It is executed after all the configuration is initialized (Local and Additional are merged and populated) and explicitly calls unset($GLOBALS['TBE_STYLES']);.

Clone a Gtk.Button from gjs

How would I go about cloning any widget from gjs, similar to the C response given in https://stackoverflow.com/a/3030603/1829961? I have not been able to find a way to call list_properties although it is listed in the GModule gir file. Or do I have to use GIRepository, manually walk the GIR type hierarchy, emulating that which g_object_class_list_properties is supposed to do? Or another straight forward way I'm totally missing here?
Here is some code that will do that.
It takes a similar approach to the quesion you linked, but since there is no G_OBJECT_GET_CLASS() in GJS, it uses GIRepository instead -- which is an extra dependency that you need compared to the C solution.

Problem using SmartTabs in Emacs

I'm trying to use smarttabs.el from https://gist.github.com/188961 in latest emacs-dev (bzr). When trying to compile or load it I get the error:
smarttabs.el:54:1:Error: Don't know how to make a localized variable an alias
which is completely new to me. How do I correct this?
Also see http://www.emacswiki.org/emacs/SmartTabs for package explanation.
The error message is trying to say that defvaralias (used in the smart-tabs-advice macro) doesn't do what jacius thinks it does. But I'm not quite sure what he thinks it does, so I'm not sure how to fix it. Try reporting the error to him.

How do I find all the modules used by a Perl script?

I'm getting ready to try to deploy some code to multiple machines. As far as I know, using a Makefile.pm to track dependencies is the best way to ensure they are installed everywhere. The problem I have is I'm not sure our Makefile.pm has been updated as this application has passed through a few different developers.
Is there any way to automatically parse through either my source or a few full runs of my program to determine exactly what versions of what modules my application is depending on? On top of that, is there any way to filter it based on CPAN packages? (So that I only depend on Moose instead of every single module that comes with Moose.)
A third related question is, if you depend on a version of a module that is not the latest, what is the best way to have someone else install it? Should I start including entire localized Perl installations with my application?
Just to be clear - you can not generically get a list of modules that the app depends on by code analysis alone. E.g. if your apps does eval { require $module; $module->import() }, where $module is passed via command line, then this can ONLY be detected by actually running the specific command line version with ALL the module values.
If you do wish to do this, you can figure out every module used by a combination of runs via:
Devel::Cover. Coverage reports would list 100% of modules used. But you don't get version #s.
Print %INC at every single possible exit point in the code as slu's answer said. This should probably be done in END{} block as well as __DIE__ handler to cover all possible exit points, and even then may be not fully 100% covering in generic case if somewhere within the program your __DIE__ handler gets overwritten.
Devel::Modlist (also mentioned by slu's answer) - the downside compared to Devel::Cover is that it does NOT seem to be able to aggregate a database across multiple sample runs like Devel::Cover does. On the plus side, it's purpose-built, so has a lot of very useful options (CPAN paths, versions).
Please note that the other module (Module::ScanDeps) does NOT seem to allow you to do runtime analysis based on arbitrary command line arguments (e.g. it seems at first glance to only allow you to execute the program with no arguments) and if that's true, is inferior to all the above 3 methods for any code that may possibly load modules dynamically.
Module::ScanDeps - Recursively scan Perl code for dependencies
Does both static and runtime scanning. Just modules, I don't know of any exact way of verifying what versions from what distributions. You could get old packages from BackPan, or just package your entire chain of local dependencies up with PAR.
You could look at %INC, see http://www.perlmonks.org/?node_id=681911 which also mentions Devel::Modlist
I would definitely use Devel::TraceUse, which also shows a tree of the modules, so it's easy to guess where they are being loaded.

What can make Class::Loader fail where "use" and "new" do not?

I'm working on a very large CGI application that uses Crypt::RSA, which is properly installed. I get a "attempted to call a null reference as a function" type of error (I can't go back to get the exact error right now because we had to rollback for a release date) when I try to run any the embedded library. I trace the null reference to Crypt::RSA's constructor, which uses Class::Loader to enable Crypt::RSA::ES::OAEP.
I replaced the class loader with a "use" and a "new", and that part works fine, though the library still fails in many points. Obviously something is wrong with my environment. I'm just not certain as to what. Can anyone give me any leads?
Ok, after 12 hours of digging into it, I got this working.
Here's what was going on (but not why). Whenever I called eval() on a quoted use or require statement (as occurs in Class::Loader, but also in other locations in the Crypt:: framwork), it failed to see paths that were otherwise included as Perl classpaths. Since most quoted use/require objects simply assume the class will be there, very few useful errors were thrown out at me. I would dump #INC to file, outside an eval block, and everything would be there.
Ironically, I used the same setup in dev vs staging, and it worked in dev, but not in staging. I must also point out that FindBin (I shouldn't be using it in CGI, I know, but Crypt uses it) was flailing up and down about /dev/null in staging, but not in development.
Since I can't easily compare versions or global configs, that's where my quest ends.
How I resolved the issue for myself in Crypt::RSA was to disable all commands tied to FindBin, and hard-code require references for anything my code would ever access. I did a require in Crypt::RSA for Crypt::RSA::ES::OAEP and one in Crypt::Random::Generator for Crypt::Random::Provider::rand
Hope this helps anyone in the future who has the problem. Anyone who can suggest the why of it, please respond and I'll add it to complete the post.