-
-
Save bazzaar/d1436636613f1f1d7e0157df204f98ec to your computer and use it in GitHub Desktop.
use Inline::Python; | |
my $py = Inline::Python.new(); | |
$py.run('import matplotlib.pyplot'); | |
class Matplotlib::Plot { | |
method cm { | |
class { | |
# this getattr method, called like so : 'say $plt.cm.getattr($cmap, 'N');' | |
method getattr($obj, $name) { | |
$py.call('__builtin__', 'getattr', $obj, $name); | |
} | |
method FALLBACK($name, $idx) { | |
$py.run("matplotlib.pyplot.cm.{$name}($idx)", :eval); | |
} | |
}.new(); | |
} | |
method FALLBACK($name, |c) { | |
$py.call('matplotlib.pyplot', $name, |c) | |
} | |
} | |
class Matplotlib { | |
method FALLBACK($name, |c) { | |
$py.call('matplotlib', $name, |c) | |
} | |
} |
use v6; | |
use lib '.'; | |
use Matplotlib_reduced; | |
my $plt = Matplotlib::Plot.new; | |
my $cmap = $plt.get_cmap('seismic', 5); | |
# -- this works | |
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N'); | |
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N'); | |
# -- this fails on the 3rd call | |
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N'); | |
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N'); | |
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N'); | |
# -- this works | |
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name'); | |
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name'); | |
# -- this fails on the 3rd call | |
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name'); | |
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name'); | |
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name'); | |
# -- this works | |
#say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N'); | |
#say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name'); | |
# -- this fails on the 3rd call | |
say 'Colormap Name : ' ~ $plt.cm.getattr($cmap, 'name'); | |
say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N'); | |
say 'Number of Colors : ' ~ $plt.cm.getattr($cmap, 'N'); | |
# -- etc.... | |
btw python's getattr
supports a third argument which is a default value in case the attribute doesn't exist.
If you write a wrapper, maybe the simplest thing to do is to create a sentinel value Any.new
as the default, and if that is returned, interpret it as not found.
More thanks 0racle, and Moritz, I definitely got way more out of this than I put in :-) I hope this thread has somehow kickstarted a future new article on your Perl6/Matplotlib blog 0racle. I agree about not bugging the Inline::Python maintainer over this when there is a work around.
It all seems so straightforward when it is explained, like you have both done in your comments, I'm not sure after a month of researching I'd have come to the same understanding :-) It's given me a whole ton of concepts and reasoning to investigate. I'll carry on with my efforts on this, and try to add some results to this gist when I have them. Thanks again.
Upon further experimentation, it seems like problems happen as soon as you start doing calls to methods on
__builtin__
. If I avoid those methods, I don't seem to hit the same problem.For example, in my
FALLBACK
in the earlier comment, if I don't check__builtin__.hasattr
then it works, but of course, Python will throw an exception if the attribute doesn't exists. You can put atry
in front of the call to__getattribute__
and it will return an undefined value (instead of throwing) if the attribute doesn't exists.I'm not yet sure how to put all these ideas together in a cohesive whole, but play around with them and see what you come up with.