Tuesday, April 23, 2013

Fedora 19: Nouveau Test Day Is The 24th

Having just received a new laptop at work (Lenovo Thinkpad T53), I was eager to load it with Fedora and get to work. But, unfortunately, there's a known bug with the nVidia graphics hardware and the nouveau drivers. If I suspend/resume my laptop, the display most likely comes back as unusable. Not locked up (I can still drop to a tty and do "init 3; init 5; exit" to get to workable desktop.

Definitely not a Good Thing™ since I like to have the laptop suspend when I close the lid to change locations, etc. I don't want to go through the whole shutdown and then startup process each time.

Fortunately, tomorrow is the Fedora 19 Test Day for Nouveau and nVidia graphics hardware! So I downloaded the latest F19 x86_64 LiveCD image, put it on a thumbdrive, and will be doing some testing later today and reporting back my findings.

Not the least of which is this one bug that's got me partially missing my old laptop.


Monday, April 1, 2013

Overriding Global Methods In Perl

In Ruby, for some work I've done recently, a coworker added some utility functions to help working with Lists, Maps and Arrays. In Ruby an array appends elements using the << operator, so by adding such an operator to his helper class he was able to have the helper code be a drop-in replacement for Ruby Arrays.

Now working in Perl, I needed to do something similar for arrays. But in Perl arrays aren't instances of any class, and my replacement is going to be just that. In Perl if you want to append to an array you use the global method:

    push(@array, $scalar);

My goal was to supplant this method with my own and, when @array is an instance of my new class (qpid::proton::ArrayHelper) do one thing. If, however, it's just a plain old Perl array then I want to call the standard function from Perl.

Sound difficult? Nope, it's easy.

Solution

To replace the global function with your own, you can simply do this:

    BEGIN {
        sub qpid_proton_push(\@ \$) {
            my (@array, $value) = @_;

            # if this is my array type, then do one thing
            if(isProtonType) {
                # do one thing
            } else {
                # call the original function
                CORE::push(@array, $value);

            }
        };
        # assign push to my new method
        *CORE::GLOBAL::push =&qpid_proton_push;
    }

The solution defines a new method and then points the global function pointer to it. The reason I chose this solution rather than pointing to an anonymous method was that I needed to declare a method prototype for qpid_proton_push. Since the first argument is an array type then a prototype was necessary to let Perl know how to handle the arguments.