Perl's Inline::Python fails on pyephem
Question: 
    #!/bin/perl 
    
    use Inline Python; 
    
    $s = new Sun(); 
    print "SUN: $s\n"; 
    $m = new Moon(); 
    
    __END__ 
    __Python__ 
    from ephem import Sun as Sun; 
    from ephem import Moon as Moon; 
    

The code above yields:

    
    
    SUN: <Sun "Sun" at 0x9ef6f14>
    Can't bless non-reference value at /usr/local/lib/perl5/site_perl/5.10.0/i386-linux-thread-multi/Inline/Python.pm line 317.
    

What's wrong? I've tried this with many other objects (eg:

    
    
    from ephem import Observer as Observer;
    

and then

    
    
    $o= new Observer();
    

in the body of my code) and it works fine for everything I've tried _EXCEPT_
Moon.

EDIT (probably useless information):

In <https://github.com/brandon-rhodes/pyephem/tree/master/libastro-3.7.5> :

  * The routines for calculating Sun, Mercury, Venus, Mars (the ones that work fine) are done in vsop87.c, function vsop87() 

  * The routines for calculating Jupiter, Saturn, etc (the ones that don't work) are done in chap95.c, function chap95() 

  * vsop87() "returns" an array of 6 doubles, which appear to be some sort of spherical coordinates. 

  * chap95() "returns" an array of 6 doubles, which appear to be Cartesian coordinates, ie, rectangular and NOT spherical. 

  * planpos() in plans.c calls one of the two functions above, depending on which planet you choose. What's odd is that planpos() treats the function results the same (sort of), even though they return very different things. 

  * After planpos(), all planets are treated the same. planpos() is called by plans() (also in plans.c), which is in turn called by obj_planet() in circum.c which is then called by obj_cir() also in circum.c 

  * obj_planet() and obj_cir() define the planet. Since planets are treated the same after planpos(), there should be no difference between them. 


Answer: It is indeed the different handling for the Moon, Jupiter and Saturn bodies,
as pointed out by Slaven in the comments. In fact, you're running into the
Python 2 issue that there is a difference between `types` and `classes`. I
can't give you the details, but there is
[quite](http://stackoverflow.com/questions/4479819/types-and-classes-in-
python) [a bit of](http://docs.python.org/2/reference/datamodel.html)
[material](http://www.python.org/download/releases/2.2/descrintro/) on the
subject.

Suffice to say, that the Python wrapper provided by PyEphem turns the bodies
into a proper class, which `Python::Inline` can handle. The Python-C wrapper,
`_libastro`, provides types instead, and thus setting `Moon` to
`_libastro.Moon` makes `Moon` a type instead of a class. Why `Python::Inline`
can deal with classes and not types, I don't know.

This, however, provides enough information for a work-around: turn
`ephem.Moon` into a class. Thus, the following may work:

    
    
    #!/usr/bin/env perl
    
    use Inline Python; 
    
    $s = new Sun(); 
    print "SUN: $s\n"; 
    $m = new Moon(); 
    print "Moon: $m\n";
    
    __END__ 
    __Python__ 
    from ephem import Sun
    from ephem import Moon
    class Moon(Moon):
        pass
    

which for me results in:

    
    
    SUN: <Sun "Sun" at 0x1f450b0>
    Moon: <Moon "Moon" at 0x20eec50>
    

You can apply the same trick to Saturn and Jupiter of course.

(I've "Pythonized" the import statements a bit: no need for `as` or semi-
colons.)

In case you'd like to verify that the Moon is still a special body even after
turning it into a class, try to use on of its special attributes, for example
`libration_lat`:

    
    
    $m->compute()
    $mllat = $m->{libration_lat};
    print "Moon: ${mllat}\n";
    
    Moon: 5:50:29.6
    

which will fail for any other type such as the Sun.

(I found these special attributes in `test_bodies.py` in the PyEphem package,
though I presume these are documented as well. In case you'd like to test for
Saturn and Jupiter, you can find them there.)

