tag:blogger.com,1999:blog-70216676194739700912018-02-06T05:23:36.432-08:00Adventures in PerlRyan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.comBlogger18125tag:blogger.com,1999:blog-7021667619473970091.post-16070634964890706272017-02-25T15:15:00.002-08:002017-02-25T15:15:19.324-08:00ABCMeta releasedThat library I mentioned was pushed to github. I will eventually release this on CPAN as well a little later. https://github.com/ryandietrich/ABCMetaRyan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com0tag:blogger.com,1999:blog-7021667619473970091.post-92180732521371971702016-12-19T12:30:00.000-08:002016-12-19T12:30:03.061-08:00A couple small adventures to mention...So, I wrote a base class for perl called ABCMeta. It does basically what python's equivalent does, but as a bonus, I do it at compile time. I plan on releasing it as soon as I write more tests to make sure I cover more of the corner cases, but I am super happy with it so far. <br/><br/> Also, I looked into the new signatures stuff in 5.20. I'm not happy. Look at the code below, tell me what I'm doing wrong. Again, compile time safety is where it's at for me at least. Please don't tell me you can see runtime errors coming as you write code. <br/><br/> <pre><br />#!/usr/bin/env perl<br /><br />package Foo;<br /><br />use strict;<br />use fields qw(a b c);<br /><br />sub new {<br /> my $self = shift;<br /> unless ( ref($self) ) {<br /> $self = fields::new($self);<br /> }<br /> return $self;<br />}<br /><br />package main;<br /><br />use strict;<br />use v5.20;<br />use feature qw(signatures);<br />no warnings qw(experimental::signatures);<br />use Data::Dumper;<br /><br />#sub mytest( Foo $obj ) : prototype($) { # XXX error types not supported on signatures?!<br />sub mytest( $obj ) : prototype($) {<br /> print Dumper($obj);<br /> eval {<br /> $obj->{'zz'} = 123; # This error is now a runtime error, not a compile time one, defeating the point of fields :-(<br /> };<br /> print "Error trying to set 'zz' on Foo! $@\n" if ( $@ );<br />}<br /><br />sub another( $obj ) {<br /> print Dumper($obj);<br />}<br /><br />sub main {<br /> my Foo $ff = Foo->new();<br /> # mytest(); # calling this without an argument will throw a compile time error, good!<br /> # &mytest(); # the sigil doesn't ignore the prototype, huh!? (uncommenting this will throw as well)<br /> mytest($ff);<br /> #another(); # more runtime errors, ugh. If I wanted to program in python..<br />}<br /><br />&main() if ( ! caller ) ; # if __name__ == 'main'<br /></pre>Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com2tag:blogger.com,1999:blog-7021667619473970091.post-4227510200039221522015-11-09T20:40:00.002-08:002015-11-09T20:40:23.160-08:00I've gone too farLong time no post. I have nearly given up on Perl, which is really sad given that I can honestly say my entire career is based on this language. My "heretical love" for compile time safety has grown even stronger, moving to even more "meta" safeties, courtesy of Java's "compile time annotations". For a long time I was happy with fields.pm, and "strict" mode. But if I am the type of person who makes fun of Python for having no compile time errors beyond syntax, then I can't look past Perl's limitations. With Java, I feel like "types" are a little more verbose, but you're either going to do the "if check" at runtime to make sure the variable is the appropriate type, so why not get the added benefit of verifying it at compile time? Course, I have to give Python it's due, threading and classes are so many orders of magnitude better than Perl it's not even funny. Then there's Boost::Python. Why couldn't there be a Boost::Perl? Man I hate XS. I want my "chocolate and peanut butter", and I don't want to program in Haskell, the only other language that seems to have the features I want in a language. So, I'm stuck with Java, until either Perl 6 "really comes out", or Go solidifies into a language worth investing time into. For now, anyone who scoffs at Java is quite literally insane. The tooling, debugging, IDE's, libraries, build tools, books, websites and documentation out there for this *wonderful* language is just way beyond anything else out there (almost all of it for free). Hoping for a better tomorrow with Perl, but happily "settling" with Java for now.Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com5tag:blogger.com,1999:blog-7021667619473970091.post-20390879358637474392010-12-31T19:56:00.000-08:002010-12-31T20:01:00.757-08:00Got two books for Christmas...1. Modern Perl, by the infamous chromatic (dude is hardcore, I don't even think his own parents know him by his real name). This is an awesome book so far (about 60 pages in), I couldn't believe I learned something I didn't know just 50 pages in. Love the detail, and love the passion in the writing style, you can totally tell this is written with a lot of desire to create something awesome for us all to have going forward.<br /><br />2. Land of Lisp, by Conrad Barski MD. I am 180 pages into this book. I never learned lisp before, and have heard from more than a few people over the years on how I should learn it (after the looked at my tactics in Perl). I have A LOT to say about this book. <br /><br />Full book reviews forthcoming. (oh and happy new year!!!!)Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com0tag:blogger.com,1999:blog-7021667619473970091.post-7198877957741190292010-09-07T09:42:00.000-07:002010-09-07T09:44:38.590-07:00Two things.1. I almost wish subroutines required the use of the ampersand sigil. I hate looking at barewords in Perl, and much prefer things to have punctuation in front so the editor picks it up with a specified color.<br />2. I learned, the very, very hard way. That the way to do XS with C++ is to use XSPP. http://search.cpan.org/~mbarbon/ExtUtils-XSpp-0.15/lib/ExtUtils/XSpp.pod I cried a little when I saw this. But, I'm incredibly thankful that it exists, even though they're a bit under the radar.Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com2tag:blogger.com,1999:blog-7021667619473970091.post-47539591272496223642010-08-04T12:17:00.000-07:002010-08-12T11:18:52.940-07:00Interfacing Perl with C++, using XS, with external files, and using the STL as parameters and return values.Preface:<br /><br />I know enough C and C++ to get things done, I'm definitely not a core Perl hacker, or any form of a low level programmer. With that in mind, there is a good chance I am incorrectly interpreting some of the terminology or the general approach. One area that I am very leery of is memory management. Just getting something working doesn't mean that you have all the leaks nailed down. That's my next task on this long, painful road. Oh, and before anyone decides to dump on my post, just keep in mind I've been trying to do this for a long time, and have bought books, scoured the internet, and asked people on forums. "This" was the BEST I could do.<br /><br />-------<br /><br />So, I have always considered XS, the "final frontier" for me with Perl. I've been coding in Perl religiously for over a decade, and have done good bit of C and C++ as well. But marrying the two together has always been a formidable task that I have feared. I've avoided it through databases, sockets, and flat files. At my old job, there was an old crufty swig file in a project we used that miraculously was able to pull things together and provide an incredibly complex interface to a shared memory data store. I tried to make sense of it a few times, but in the end (due to a general lack of time and documentation) I ended up just trusting in the magic, and hoped that the swig code never broke.<br /><br />I have built a few components in C++ that I am really proud of, and decided it was time to figure out how to link my beloved Perl to the world of C++. I like to think I am good at researching programming problems. I should really re-state this as, I am really good at using google, to solve compex programming problems. Sadly it's more like "I've never done anything unique, and anything I have problems with someone else has already had, and posted about it, years ago, and garnered responses from the luminaries that lead our community". I just am good enough with Google to find those threads to get me in the right direction to solve whatever problem I'm having, when my army of O'Reilley books aren't there to teach me what I need to know.<br /><br />Here is my task. I have a C++ library, that I would like to be able to access from perl. The library is object oriented, takes strings as arguments, and returns strings, or vectors of strings, or hashes of strings/strings. I'll be honest, I'm not a C++ guru, I have used Boost and ACE to write safe multi-threaded code, and I have a decent understanding of memory management in C/C++ but that is pretty much the end for me.<br /><br />---- BEGIN BOOK REVIEW<br /><br />Disclaimer: This isn't a book review ;-), but I figured I'd make a few comments on this book I paid $44.99 for, since it's directly applicable to my problem.<br /><br />To start off, I am staring at a copy of "Extending and Embedding Perl", by Tim Jenness and Simon Cozens. It is an odd book. Two of the eleven chapters are spent teaching you C, and two more chapters are spent discussing how to hack Perl itself. The rest of the book is a bit more applicable to the title, with two chapters devoted to embedding perl and five chapters to extending. (though, "Alternatives to XS" could have been a much larger topic, but I'll get to that later).<br /><br />The reason I point out the distribution of material in the book is, in those 4 chapters about using XS, it misses the most basic use case in all of the examples. Linking Perl to an existing C or C++ library. Every single one of their examples shows the C code being embedded in the ".xs" file directly. There is no mention of how you would even accomplish this, anywhere in the book! Just to prove the point, go download the example code yourself and do an "find . |egrep -i '\.[ch]$'". You won't find anything outside of chapters one and three, the ones that deal with teaching you C, and a short blib on h2xs in chapter 7, but even that shows you the actual C code in the ".xs" file.<br /><br />There are 7 pages devoted to extending to C++. I typed in the examples, and with a little work, got them working. The example didn't cover external files, nor did it cover how to pass complex variables (the examples dealt with "int's" for input an output). So for, to summarize (finally), this is a good reference book, and when I actually need to jerk around with SV's and HV's, and IV's, then I can learn what they are and how they work.<br /><br />If I could change it, I'd just get rid of all the extra stuff, and make more room for XS and Perl's internals. If there was room to spare, maybe full chapters on Swig and Inline, as they are both solid solutions that deserve more than short mentions.<br /><br />---- END BOOK REVIEW<br /><br />Thus begun my internet search.<br /><br />I started at Perlmonks. Queries concerning: "XS C++" and "XS external library" were fruitless for the most part. http://perlmonks.org/?node_id=517931 .. tye, had the most impressive response (yes, I upvoted him), but it only dealt with C++ loaded directly in the XS file, and with "char's".<br /><br />Then I hit the chatterbox. tye of course was online, being the helpful guy he is held an amazing amount of patience with me as I slowly answered my questions. He did his absolute best to steer me away from XS entirely, and to use SWIG or Inline::C++ instead. But my position was simple, I didn't see any of the "awesome" libraries on CPAN resorting to this, why should I? Why is this so damn hard? Why is it so poorly documented? Why do I have a book on the subject that I paid 50$ for and I still have no clue how to accomplish such simple tasks? tye sensed my frusrtration, and kept pressing for alternatives. It was at this point I decided that I'd play the "Picard" card with XS.<br /><br />"They invade our space, and we fall back. They assimilate countless worlds, and we fall back. Not again. Not this time. The line must be drawn here! This far, no farther! And I will make them pay for what they have done!" - Jean Luc Picard, Star Trek First Contact<br /><br />Come hell or high water (?) I am going to figure this out.<br /><br />-------<br /><br />But first, let's take a look at why I didn't want to use Inline::C++, or SWIG.<br /><br />Inline::C++ : This module, when it works, works really well. It provides a seemless integration between Perl and C++, and you barely have to lift a finger. The people who wrote this are beyond smart. I applaud their work. Here is where it breaks down for me. You need to have a compiler and your environment set up the same way for every machine that you want to use your library on (unless you do even more smart env logic in your BEGIN blocks). If you don't have a compiler, and/or don't want to rely on re-compiling when you run the program, I'm told you can distribute the compiled bits, but packaging this became almost as much of a daunting task as the original problem itself.<br /><br />SWIG : I used to work with a guy who worked on the SWIG team. His initials are "M.M" (for friends of mine that read this). Nobody can understand a word he says (in English), as he's from Chile, but what is funny is nobody can understand what he says in spanish eiher (and that comes from people who are native spanish speakers). Heh, anyway, that's sort of how SWIG is. You tell it to do something, and either it works, or it spits back unintelligble mess that is totally undecipherable. Just like my old job, you have to trust the magic, and if it breaks, you have no recourse. Their website has decent documentation, but not enough detail on how to resolve complex issues, leaving you to scour the internet like I did on XS. Do you use an abstraction that will have problems, but a smaller pool of people that can help? Or do you tough it out and use the harder solution, but one that has a larger pool of support? Guess which one I'm going with.<br /><br />-------<br /><br />I tried to just look at existing perl modules that I knew linked to C/C++ on CPAN. I knew libxml, Wx, and the various DBD::* libraries had to make calls to the underlying layers, but the typemaps were far too complex for my puny mind to comprehend. I hoped the Wx library would have some insight, but it too blew my mind. I needed a concrete example or documentation on what steps needed to be taken.<br /><br />-------<br /><br /><a href="http://www.johnkeiser.com/perl-xs-c++.html">John Keiser</a> seems almost as frustrated as I am. This link is referenced in MANY other articles on the internet concerning XS and C++. Of course, this doesn't have an example of using external files, and ::sigh:: it only deals with int's for inputs and outputs. Sadly, since this was written in 2001, I ran into some issues just getting the examples working. In the end, I just gave up on it and looked for other documentation.<br /><br />-------<br /><br /><a href="http://stackoverflow.com/questions/428153/how-do-i-call-a-c-static-library-from-perl">Stack Overflow</a> is a pretty good place to get answers to questions, most of the answers pointed to SWIG, Inline::C, and the perl-xs-tut (we'll get to the xs-tut here in a second).<br /><br />-------<br /><br />Perl XS Mail Archive <a href="http://www.mail-archive.com/perl-xs@perl.org/msg00889.html">1</a> and <a href="http://www.mail-archive.com/perl-xs@perl.org/msg00631.html">2</a> : I found these gems, while digging, and it gave me hope that building a typemap for std::string and std::vector might be possible. Unfortunately, the code was meant more as a scratchpad (and he states this explicitly). So close!<br /><br /><a href="http://www.mail-archive.com/perl-xs@perl.org/info.html">The Perl XS archive</a> : Incidentally, the Perl XS mailing list is a really great site. This place has a great signal to noise ratio (similar to the mod_perl mailing list). Yet again, things that I have questioned, more or less, have already been asked, answered, or told they are thinking about the problem wrong (the latter being my problem).<br /><br />-------<br /><br /><a href="http://www.mail-archive.com/perl-xs@perl.org/msg01965.html">Boom</a>, here was some documentation of an external file with XS. Lots of concepts and little example though. I really wanted everything explained, no more magic. I could probably figure things out from here, but I'm going to keep hunting.<br /><br />-------<br /><br /><a href="http://science.larc.nasa.gov/ceres/presentations/WrappingPerl.ppt">WrappingPerl.ppt</a> : Uses external files! Uses the STL!! ... Uses SWIG. Damn it. Ok, so I typed all this out, and got it working, and tried to figure out what SWIG was generating based on the resulting ".cxx" file. It ended up being another brick wall. I was impressed that SWIG was capable of doing almost everything I needed it to do, but it was the same magic that I had to "trust" like I did back in my previous job. I decided that I was NOT going to use swig.<br /><br />-------<br /><br /><a href="http://perl.org.il/presentations/offer_kaye_swig/index.html">SwigKaye</a> : An even better SWIG example. It was recently posted to Alberto Simões's perl blog by Kaye (courtesy of Shlomo Yona). This is the best SWIG documentation that deals with complex data structures and external files available. If anyone else writes a book about XS, they should just dump this entire distribution to paper, as it is incredibly well documented. Too bad it's C, otherwise I probably would have given up XS and just used this.<br /><br />-------<br /><br /><a href="http://perldoc.perl.org/perlxstut.html">perlxstut</a> : Yes! Why the hell didn't I look here first?! Example 4 is perfect! External files! MYEXTLIB! (wtf is an MYEXTLIB?!)<br /><br />As an aside, look at the perldoc for ExtUtils::Makemaker, under MYEXTLIB, and see if you make the connection that THIS is the attribute that allows you to reference external libraries, yes I know EXTLIB should have clued me in, but it didn't register as the solution to my problem).<br /><br />Holy crap the ExtUtils::MakeMaker is complicated. Where the heck did this "MY" namespace come from? What is all this weird "make" snippets littered all around? Ok, just get it working, and then you can reverse engineer it so you can teach yourself what all these keywords mean so you can actually learn something, rather than trusting the "magic". So that's what I did. (I'll cover that when I finally get to the example).<br /><br />I used Module::Install for my last CPAN projet, "Ravenel". I wondered if it could build XS modules as well. But it's funny to me, since everyone seems to hate ExtUtils::MakeMaker, but all the modules that use XS all use it. It looks like this is the only syste worth using if you're dealing with this stuff.<br /><br />-------<br /><br />Ok, let's not get too excited, I still need to know how to build a typemap for STL based objects, and if it's possible, complex ones (Vectors and Maps).<br /><br />Typically, in any google search of a technical nature, you inevitable will start seeing posts in languages other than your own, I don't start hitting these until I exhaust all of the ones that are in english (obviously). (What do you call someone who is in Europe and can speak 5 languages? A waiter. What do you call someone who speaks one language and who is in Europe? An American.) Google translate does a decent job of getting the point across, but the concepts backing the idea always seem to be lost in translation (love that movie).<br /><br /><a href="http://d.hatena.ne.jp/higepon/20060223/1140684810">Japanese Perl blog</a> : I ran into this first. And I thought I finally found it. The typemaps that wrap the STL for Perl. I have a "simple" class that you instantiate with a string as an arugment, and some methods that take strings and spit them back out. This is formatted for SWIG, and combined with the earlier lesson I found on swig, I probably could have just got by with this. But I've come too far now. XS or bust!<br /><br />-------<br /><br /><a href="http://translate.google.com/translate?js=y&amp;prev=_t&amp;hl=en&amp;ie=UTF-8&amp;layout=1&amp;eotf=1&amp;u=http%3A%2F%2Fblog.livedoor.jp%2Fkurt0027%2Farchives%2Fcat_50014038.html&amp;sl=ja&amp;tl=en">Holly's Blog!</a> : But, this, is when I hit the proverbial jackpot. "Holly's page". I don't know who Holly is, but he/she is amazing and I wish I could sing his or her praises from the tallest buildings / trees / mountains. Holly has a 9 part XS C++ programming course on his or her site "The introduction perlxs 1-9". It covers damn near everything I would ever want to know about XS, with concrete examples.<br /><br />Dear Holly, you rock, you have my undying devotion until the end of time, because you have documented your brilliance with so much clarity that I was able to translate it from Japanese and still get what I needed out of it. I owe you a beer, sake, fruit juice, or whatever it is you drink. Thank you from the bottom of my beaten down soul. --dextius<br /><br />-------<br /><br />I feel better now that I've gotten that diatribe out of the way. Let's show you an example of using an external library, passing strings back and forth between Perl and C++. Then, let's explain what every line does so we can demystify some of the magic and fear that comes when dealing with XS. Before I dump out all my code, there is one point I need to make. I found it's easier to abandon your build script that you normally use to build your C++ project, and just use what Makefile.PL generates. I accomplished this by simply copying my code into this new directory tree.<br /><br />Change directories in your shell to somewhere where you can create new stuff and then run this.<br /><br /> h2xs -A -n SimpleTest<br /><br />This will create a skeleton for us to work with. Now create the SimpleLib directory.<br /><br /> mkdir SimpleTest/SimpleLib<br /><br />Here is the code for our "simple" library.<br /><br /><h2>/SimpleTest/SimpleLib/Simple.h</h2><br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>#include &lt;string&gt;<br />#include &lt;map&gt;<br />#include &lt;vector&gt;<br /><br />using namespace std;<br /><br />typedef map&lt;string,string&gt; StringMap;<br />typedef StringMap::iterator StringMapIt;<br /><br />typedef vector&lt;string&gt; StringVector;<br />typedef StringVector::iterator StringVectorIt;<br /><br />class Simple {<br /> public:<br /> Simple(int myArg);<br /> int add(int myArg);<br /> std::string get_string(std::string str);<br /> StringMap getMap(StringMap myMap);<br /> StringVector getVec(StringVector myVec);<br /> protected:<br /> int myInt;<br />};<br /></code></pre><br /><br /><h2>/SimpleTest/SimpleLib/Simple.c</h2><br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>#include &quot;Simple.H&quot;<br />#include &lt;string&gt;<br /><br />Simple::Simple(int myArg) {<br /> myInt = myArg;<br /> return;<br />}<br /><br />int Simple::add( int myArg ) {<br /> return myInt + myArg;<br />}<br /><br />std::string Simple::get_string( std::string str ) {<br /> std::string foo = &quot;&#124;&quot; + str + &quot;&#124;&quot;;<br /> return foo;<br />}<br /><br />StringMap Simple::getMap(StringMap myMap) {<br /> myMap[&quot;Hello&quot;] = &quot;world&quot;;<br /> return myMap;<br />}<br /><br />StringVector Simple::getVec(StringVector myVec) {<br /> myVec.push_back(&quot;abc&quot;);<br /> myVec.push_back(&quot;123&quot;);<br /> return myVec;<br />}<br /></code></pre><br /><br /><br /><h2>/SimpleTest/SimpleLib/Makefile.PL</h2><br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><br /><br />use ExtUtils::MakeMaker;<br /><br />( $CC, $Verbose ) = ( 'g++4', 1 );<br />WriteMakefile(<br /> NAME => 'Simple::SimpleLib',<br /> SKIP => [qw(all static static_lib dynamic dynamic_lib)],<br /> clean => {'FILES' => 'libSimpleLib$(LIB_EXT) unitTests'},<br /> CC => $CC,<br /> LD => '$(CC)',<br /> CCFLAGS => '-fPIC',<br />);<br /><br />sub MY::top_targets {<br /> '<br />all :: static<br /><br />pure_all :: static<br /><br />static :: libSimpleLib$(LIB_EXT)<br /><br />libSimpleLib$(LIB_EXT): $(O_FILES)<br /> $(AR) cr libSimpleLib$(LIB_EXT) $(O_FILES)<br /> $(RANLIB) libSimpleLib$(LIB_EXT)<br /><br />bin: $(O_FILES)<br /> $(LD) $(O_FILES) -o unitTests<br /> ';<br />}<br /><br /><br /></code></pre><br /><br /><h2>/SimpleTest/SimpleLib/unitTests.c (A quick test "main")</h2><br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><br />#include &quot;Simple.H&quot;<br />#include &lt;iostream&gt;<br />#include &lt;string&gt;<br /><br />int main( int argc, char * argv[] ) {<br /><br /> Simple s = Simple(5);<br /> std::cout &lt;&lt; s.add(9) &lt;&lt; std::endl;<br /><br /> std::string moo = &quot;abc&quot;;<br /> std::string foo = s.get_string(moo);<br /><br /> std::cout &lt;&lt; foo &lt;&lt; std::endl;<br /><br /> StringMap m;<br /> m[&quot;qqq&quot;] = &quot;uuu&quot;;<br /><br /> StringMap n = s.getMap(m);<br /> std::cout &lt;&lt; &quot;n[qqq] &quot; &lt;&lt; n[&quot;qqq&quot;] &lt;&lt; std::endl;<br /><br /> StringVector v;<br /> v.push_back(&quot;999&quot;);<br /><br /> StringVector w = s.getVec(v);<br /> std::cout &lt;&lt; &quot;w[0] &quot; &lt;&lt; w[0] &lt;&lt; std::endl;<br /> std::cout &lt;&lt; &quot;w[1] &quot; &lt;&lt; w[1] &lt;&lt; std::endl;<br /> std::cout &lt;&lt; &quot;w[2] &quot; &lt;&lt; w[2] &lt;&lt; std::endl;<br /><br /> return 0;<br />}<br /></code></pre><br /><br />-------<br /><br />At this point, you can compile "SimpleLib". You'll run these commands.<br /><br /><pre><br />perl Makefile.PL<br />make<br />make bin<br /></pre><br /><br />To verify, run the unitTests binary.<br /><br /><pre><br />./unitTests<br /></pre><br /><br />It should return:<br /><br /><pre><br />14<br />|abc|<br /></pre><br />-------<br /><br />Before I go any further, lets look at the Makefile.PL as it is key to all of our future plans.<br /><br />1. We need to build a shared library, "make" will generate the "libSimpleLib.a" file.<br />2. "make bin" will generate the unitTests binary, running a "file unitTests" will tell you what architecture you're building for.<br />3. It is important your version of Perl was compiled with the same architecture (perl -v will tell you this).<br />4. A great resource on make is available here: http://www.cprogramming.com/tutorial/makefiles.html<br /><br />Ok.<br /><br />Great, now we have a shared library built, and trust that it actually is capable of doing something when told to (via the unitTests binary). Now let's hook this up to Perl.<br /><br /><h2>/SimpleTest/Makefile.PL</h2><br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code><br /><br />use 5.008003;<br />use ExtUtils::MakeMaker;<br /><br />$CC = 'g++';<br /><br /># See lib/ExtUtils/MakeMaker.pm for details of how to influence<br /># the contents of the Makefile that is written.<br />WriteMakefile(<br /> NAME =&gt; 'Simple',<br /> VERSION_FROM =&gt; 'lib/Simple.pm', # finds $VERSION<br /> PREREQ_PM =&gt; {}, # e.g., Module::Name =&gt; 1.1<br /> CC =&gt; $CC,<br /> LD =&gt; '$(CC)',<br /> ($] &gt;= 5.005 ? ## Add these new keywords supported since 5.005<br /> (ABSTRACT_FROM =&gt; 'lib/Simple.pm', # retrieve abstract from module<br /> AUTHOR =&gt; 'dextius &lt;dextius@blahblah.com&gt;') : ()),<br /> LIBS =&gt; [''], # e.g., '-lm'<br /> DEFINE =&gt; '', # e.g., '-DHAVE_SOMETHING'<br /> INC =&gt; '-I.', # e.g., '-I. -I/usr/include/other'<br /> # OBJECT =&gt; '$(O_FILES)', # link all the C files too # Un-comment this if you add C files to link with later:<br /> # target the shared library we just created &quot;MYEXTLIB&quot; tells make to use this shared library.<br /> 'MYEXTLIB' =&gt; 'SimpleLib/libSimpleLib$(LIB_EXT)',<br />);<br /><br /># (THE INDENTION on &quot;cd SimpleLib...&quot; MUST BE A TAB)<br /><br />sub MY::postamble {<br />'<br />$(MYEXTLIB): SimpleLib/Makefile<br /> cd SimpleLib &amp;&amp; $(MAKE) $(PASSTHRU)<br />';<br />}<br /></code></pre><br /><br /><h2>/SimpleTest/Simple.xs</h2><br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code># Ahh now we are getting to the meat and potatoes of this monster.<br /># Most of this mess is generated by h2xs, but let's see what else we got.<br /><br />#include &quot;EXTERN.h&quot;<br />#include &quot;perl.h&quot;<br />#include &quot;XSUB.h&quot;<br /><br />#include &quot;ppport.h&quot;<br /><br /># This line being ABOVE the &quot;MODULE =&quot; line is critical, as everything above that line is treated as pure C++<br /># Anything below it is in XS macro land.<br /><br />#include &quot;SimpleLib/Simple.h&quot;<br /><br />using namespace std;<br /><br />MODULE = Simple PACKAGE = Simple<br /><br /># The constructor. Kind of looks like C++ here. I pass in an &quot;int&quot;.<br /><br />Simple *<br />Simple::new( y )<br /> int y<br /><br /># I have no idea how &quot;SimplePtr&quot; became a valid keyword, but somehow the XS engine realizes that it is the return type of the constructor.<br /># It's magic to me, for now.<br /><br />MODULE = Simple PACKAGE = SimplePtr<br /><br /># Here is some basic XS, the documentation on this is covered pretty well in &quot;Extending and Embedding Perl&quot;, specifically chapters 2 and 6.<br /><br />int<br />Simple::add(x)<br /> int x<br /> OUTPUT:<br /> RETVAL<br /><br />string<br />Simple::get_string(z)<br /> string z<br /> OUTPUT:<br /> RETVAL<br /><br />StringMap<br />Simple::getMap(myMap)<br /> StringMap myMap<br /> OUTPUT:<br /> RETVAL<br /><br />StringVector<br />Simple::getVec(myVec)<br /> StringVector myVec<br /> OUTPUT:<br /> RETVAL<br /><br /></code></pre><br /><br /><h2>/SimpleTest/typemap</h2><br /><br /><pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>TYPEMAP<br />Simple * T_PTROBJ<br />string T_STRING<br />StringMap T_STRING_MAP<br />StringVector T_STRING_VECTOR<br /><br /># Ok, let's step through this one fragment at a time. First we're going to declare the &quot;input&quot; type<br /># (ie: an argument passed in from perl to C++) of T_STRING, which maps to the C++ STL type of std::string.<br />#<br /># SvTYPE is a function that looks at an SV's type to determine if it's an ordinary SV.<br /># It's basically the XS version of &quot;ref&quot;. SVt_PV is a string. But you should use SvROK (the other half of &quot;ref&quot;)<br /># first, not sure why it's not. If the string typemap receives something that isn't one, it'll warn and return undef.<br /><br /># SvCUR is a function that lets you interrogate the length of a scalar.<br /># SvCUR has a friend named SvLEN that tells you how long it could be.<br /># If it's length is 0, warn and return undef (not always desired, but for now it's fine.<br /><br /># The last line generates a string from the argument given.<br /># &quot;string&quot; is the actual C++ class constructor.<br /># SvPV_nolen lets you extract the value of a scalar and coerce it as a char *,<br /># of unlimited length, because the C++ std::string constructor doesn't care, I think.<br /><br />INPUT<br />T_STRING<br /> {<br /> if (SvTYPE($arg) != SVt_PV) {<br /> warn(\&quot;${Package}::$func_name() -- $var is invalid svtype\&quot;);<br /> XSRETURN_UNDEF;<br /> }<br /> if (SvCUR($arg) == 0) {<br /> warn(\&quot;${Package}::$func_name() -- $var is empty\&quot;);<br /> XSRETURN_UNDEF;<br /> }<br /> $var = string(SvPV_nolen($arg));<br /> }<br /><br /># Ok, this next section covers strings returned from C++ functions or methods (hence the OUTPUT),<br /># that need to be transformed back into scalars for perl to deal with. The &quot;sv_setpvn&quot; macro sets<br /># the value of a scalar.<br /><br />OUTPUT<br />T_STRING<br /> sv_setpvn($arg, $var.c_str(), $var.size());<br /><br /><br /># Now things get complicated, let's handle an &quot;array reference&quot; and turn it into a std::vector of std::string's<br /># and pass it into a C++ function or method, yee-hah..<br />#<br /># AV *av is a perl array.<br /># I32 len is a 32 bit int. (why not just use int?)<br /># SvROK &quot;is this a reference&quot; sort of like ref, except it doesn't tell you which kind. (SvRV dereferences the reference)<br /># SVt_PVAV is Perl's C structure for an Array.<br /># So, the entire line says, &quot;if the argument is a perl array reference:&quot;<br /># Dereference the arg, then downcast it to a pointer of an array type (since we know it is one), assign that to our array type (av).<br /># Assign the length of the arraa, using &quot;av_len&quot;.<br /># We return undef if it's length is 0 (not sure why we couldn't return an empty list here, but whatever)<br /># The &quot;else&quot; handles the case when it's not handed an array reference as an argument<br />#<br /># Now for the guts. Iterate over every element (the for loop)..Call the vector's method &quot;push_back&quot;.<br /># Create a new string, calling the scalar extraction SvPV_nolen, against the dereferenced value of what av_fetch returned.<br /># It passes the array, the position, and a third argument detailing if Perl needs to auto extend the list<br /># (because you're about to write to that index position). av_fetch returns a pointer to a pointer to an SV, hence the deref'ing &quot;*av_fetch&quot;.<br /># lastly, we need to assign the &quot;$var&quot; (what goes to C++ to t_sv, our C++ StringVector, the header shows this is a std::vector&lt;std::string&gt;<br /><br />INPUT<br />T_STRING_VECTOR<br /> {<br /> AV *av;<br /> I32 len;<br /> StringVector t_sv;<br /> if(SvROK($arg) &amp;&amp; SvTYPE(SvRV($arg)) == SVt_PVAV){<br /> av = (AV *)SvRV($arg);<br /> len = av_len(av) + 1;<br /> if(len == 0){<br /> warn(\&quot;${Package}::$func_name() -- $var is empty array reference\&quot;);<br /> XSRETURN_UNDEF;<br /> }<br /><br /> } else {<br /> warn(\&quot;${Package}::$func_name() -- $var is not a array reference\&quot;);<br /> XSRETURN_UNDEF;<br /> }<br /> for (I32 i = 0; i &lt; len; i++) {<br /> t_sv.push_back(string(SvPV_nolen(*av_fetch(av, i, 0))));<br /> }<br /> $var = t_sv;<br /> }<br /><br /># Now for String vectors returned back to Perl<br /># If it the C++ vector is empty, it returns undef back to perl<br /># Why is it when I see &quot;sv_2mortal&quot; I think about the intro to the Sega game, &quot;Altered Beast&quot;... &quot;Rise from your grave!&quot;<br /># So many weirdly named keywords in Perl. I love the language, maybe even because of it's quirks.<br />#<br /># Anyway, we create a new Array. (the rest is covered similarly on page 124 of Extending and Embedding Perl).<br />#<br /># SvSetSV will COPY the data from one variable to another, unless they're pointing to the same thing.<br /># newRV_noinc: This is the C/C++ equivalent of the &quot;\&quot; or reference operator. We have a list, we want to return it as an array reference.<br /># We don't increment because it needs to go out of scope when this block finishes (we're copying to &quot;arg&quot; anyway, so the data lives on).<br /># Reading from inside out. Take an array, cast it as a pointer to a scalar (what newRV_noinc requires). Pass that to newRV_noinc to<br /># create a reference. &quot;arg&quot; and this new reference value get sent to SvSetSV to copy the contents of your new array ref to the outbound<br /># &quot;arg&quot; structure. Phew!<br /><br />T_STRING_VECTOR<br /> {<br /> if($var.empty()){<br /> warn(\&quot;${Package}::$func_name() -- vector is empty\&quot;);<br /> XSRETURN_UNDEF;<br /> }<br /><br /> AV *av = (AV *)sv_2mortal((SV *)newAV());<br /> for(StringVectorIt it = $var.begin(); it != $var.end(); it++) {<br /> av_push(av, newSVpvn(it-&gt;c_str(), it-&gt;size()));<br /> }<br /> SvSetSV($arg, newRV_noinc((SV *)av));<br /> }<br /><br /># Now we need to look at hash referenecs passed as arguments to C++ functions.<br /># They'll transform into std::map&lt;std::string, std::string&gt;.<br /># HV is a hash value<br /># HE is a hash entry (a key)<br /># Ok, we've seen most of this already. So let's move quick.<br /># If it's not a hash ref, the return undef (SVt_PVHV is a hash)<br /># Next is the C side perl loop over the keys in a hash<br /># The key and value from the hash get forced into scalar values via HeSVKEY_force and HeVAL.<br /># Those scalars are passed into the insert function of our StringMap (std::map&lt;std::string, std::string&gt;)<br /># Assign the ingoing $var to the StringMap we've been inserting into!<br /><br />INPUT<br />T_STRING_MAP<br /> {<br /> HV *hv;<br /> HE *he;<br /> StringMap t_sm;<br /> if(SvROK($arg) &amp;&amp; SvTYPE(SvRV($arg)) == SVt_PVHV) {<br /> hv = (HV *)SvRV($arg);<br /> if(hv_iterinit(hv) == 0) {<br /> warn(\&quot;${Package}::$func_name() -- $var is empty hash reference\&quot;);<br /> XSRETURN_UNDEF;<br /> }<br /> } else {<br /> warn(\&quot;${Package}::$func_name() -- $var is not a hash reference\&quot;);<br /> XSRETURN_UNDEF;<br /> }<br /><br /> while((he = hv_iternext(hv)) != NULL) {<br /> SV *svkey = HeSVKEY_force(he);<br /> SV *svval = HeVAL(he);<br /> t_sm.insert(StringMap::value_type(string(SvPV_nolen(svkey)), string(SvPV_nolen(svval))));<br /> }<br /> $var = t_sm;<br /> }<br /># Lastly, deal with functions / methods that return StringMap's back to Perl.<br /># If it's empty, return undef..<br /># That crazy 'rise from the dead' thing again creating a Hash value that will go out of scope and be freed after this block ends.<br /># Now it's basic C++ map looping. hv_store only takes 5 arguments. ::blink::<br /># The hash that you want insert into<br /># A const char* of the key<br /># An I32 integer of the length of that char* key we just mentioned<br /># A scalar that is to be the value of the key.<br /># The hashing value (passing 0 will tell Perl to compute it for you)<br /># it-&gt;first is the key of the current element in std::map<br /># it-&gt;second is the value of the current element in std::map<br /># The value needs to be &quot;wrapped&quot; by the creation of a new scalar value, same as what we did when adding elements to an array<br /><br />OUTPUT<br />T_STRING_MAP<br /> {<br /> if($var.empty()){<br /> warn(\&quot;${Package}::$func_name() -- map is empty\&quot;);<br /> XSRETURN_UNDEF;<br /> }<br /> HV *hv = (HV *)sv_2mortal((SV *)newHV());<br /> for(StringMapIt it = $var.begin(); it != $var.end(); it++) {<br /> hv_store(hv, (it-&gt;first).c_str(), (it-&gt;first).size(), newSVpvn((it-&gt;second).c_str(), (it-&gt;second).size()), 0);<br /> }<br /> SvSetSV($arg, newRV_noinc((SV *)hv));<br /> }<br /><br /></code></pre><br /><br />---------<br /><br />What do I do when I get: "error: macro "do_open" requires 7 arguments, but only 2 given"<br /><br />While I'm here, I ran to a bunch of other fun issues. Linking to Boost or ACE causes all kinds of wacky symbol collisions to fire off, but google was to the rescue, again. Simple add these few lines to your ".xs" file (immediately after #include "ppport.h")<br /><br /><pre><br />#undef init_tm<br />#undef do_open<br />#undef do_close<br /><br />#ifdef ENTER<br />#undef ENTER<br />#endif<br /></pre><br /><br />-------<br /><br /><a href="http://www.mail-archive.com/perl-xs@perl.org/msg02252.html">Exceptions?</a> <br /><br />So, my code throws exceptions. I cannot catch them, they cause Perl to blow up. I looked around, and eventually found the link above. It, like most of what I have learned about XS frightened me. I can see this is another "spend a week" researching on how other people have approached the problem, and then hack something of my own together, but hopefully someone will read this and tell me what the best approach is.<br /><br />-------<br /><br />Multiple C++ objects exposed by XS (in a single project)?<br /><br />Wx does this, but it uses it's own custom MakeMaker to pull it off. The one thing I noticed is that it created seperate .xs files for each class. I assume this is what I need to do, but I don't know how to make Makefile.PL pick up the other .xs files I create describing the other objects defined in my header file. I also learned (the hard way) you can't define more than one object in a ".xs" file, or maybe it's just the syntax I was using. I really don't know. I wish I had a few weeks to reverse engineer how Wx is doing this, but there is so *MUCH* code, I'm not even sure where to start.<br /><br />-------<br /><br />Summary: Wow, this was really hard. I still don't know everything. I feel like after pouring over Extending and Embedding Perl over the last month or so I can tackle a C based library with some level of competency. But beyond these simple STL calls and an object wrapper, I still feel totally lost with C++ and XS. So many burning questions, and so few outlets for more information. Again, if I didn't stated it before, the fact that I got any of this working at all wouldn't have been possible with out "Holly's Blog". It's amazing how much information is on that page. It's ironic, that I had to go through Japanese to to get to XS (both of which being undecipherable to me).<br /><br />Hopefully this mess I have written will inspire much more talented people to write even better documentation so I can update this entire page with a simple link to their page. :-)Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com16tag:blogger.com,1999:blog-7021667619473970091.post-47918859261653862722010-08-03T10:41:00.000-07:002010-08-03T10:52:46.060-07:00A few thoughts..1. I missed the YAPC::NA conference due to "degenerative disc disease". The short story is the pads in between my vertebrae are going away slowly, so I have to get on the physical therapy stat! <br /><br />2. Rakudo * is out!! Woooo!!!<br /><br />3. Why are people hammering Rakudo * for it's speed? It's still faster than Java when it first came out (and I remember those dark days ::shudder::). They clearly stated that nobody had bothered optimizing anything in the code. It makes me sad that people are going to be hurt by these other blogs. I hope they keep their spirits up. Whether they realize it or not, they are the giants, the shoulders that we stand upon.<br /><br />4. I REALLY hope that the Parrot and Rakudo teams don't take their eyes off the ball because of these stupid speed posts. You only really get one "chance" to get all this right (unless we're talking about Perl 7). I'd rather them take another year to finalize the language specification than rush off to start pouring cement into what they have as a reaction to some blog posts.<br /><br />5. I am preparing the mother of all XS posts. I'll probably post it on perlmonks as well, since I had some conversations with some people on the chatterbox. I have a bad feeling it will not be received as well as I hope it will (I'm a little critical), but after fighting, learning, and getting nowhere for weekss before catching a few breaks, I think my story is worth reading.Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com2tag:blogger.com,1999:blog-7021667619473970091.post-61720073211280801582010-05-21T06:33:00.000-07:002010-05-21T06:59:03.919-07:00Sooooo excitedhttp://blogs.perl.org/users/doubi/2010/05/introduction-and-api-spec.html<br /><br />I really, really do not enjoy messing around with XS. Being that it is this weird "smerge" of perl and C. I have a few books on the subject, and even after reading them all, and reading examples, and reading tutorials on the web, I still can't seem to ever get it all right. I know that these things come with time, and what XS accomplishes isn't exactly simple stuff, so I should be happy I'm not hand coding it in assembly or whatever.<br /><br />But ctypes, ::sigh:: those guys in the python world hold that damn library over my head like hammer. Any time I talk about how awesome Perl is, they bring up the drudgery and over-complexity that XS brings to the table when it's time to interface with other languages (while maintaining performance). <br /><br />I am very thankful for GSoC, and for Ryan Jendoubi and Reini Urban. Good luck gentlemen! If I can help test, or write documentation or something, let me know. (it would probably be best if I stayed out of the code on this one).Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com22tag:blogger.com,1999:blog-7021667619473970091.post-14930426805871973182010-05-18T06:12:00.000-07:002010-05-18T06:18:28.549-07:00Strawberry Perl!So I installed Strawberry Perl on my PC a few days ago. A few points.<br /><br />1. What an awesome website. It looks great, is totally functional, and gets to the point quickly.<br />2. Simple and easy installer.<br />3. I'm so used to typing #!/usr/bin/perl .. Might take a while to get used to it's full pathname.<br />4. As much as I have loved ActiveState Perl over the years when coding on Windows, I feel a lot more at home with Strawberry. It feels like someone who knows Perl and Unix, and dealt with Perl using Cygwin decided to just build something better altogether. This is basically what happened.<br /><br />So congrat's, you have earned your 30+ meg of disk space on my beloved 80gig Intel SSD :-)Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com5tag:blogger.com,1999:blog-7021667619473970091.post-24035321510934853312010-05-05T18:51:00.000-07:002010-05-05T18:56:03.915-07:00Ironman Fail!Yeah, the ironman thing was a post a week. I haven't posted in nearly a year. I suck. Since my last post, I have changed jobs, moved to Chicago, and I wrote my own templating system (don't cheer all at once ;-) .. )<br /><br />Anyway, it's called Ravenel. It's a weird hybrid between a bunch of different templating systems I've used over the years, and I honestly really like what I've made. I'll post some more in depth examples here real soon.<br /><br />In other news. I just signed up to attend the YAPC::NA conference that will be taking place in Columbus Ohio. If anyone out there is in Chicago, and needs a ride, let me know, as I'll be driving down Sunday, and returning around noon on Wednesday. Should be awesome. <br /><br />Can't wait to see Rakudo Star. Best wishes to PM and his family.<br /><br />Lastly, a new version of Perl 5! I wonder how long it will take for us to see this used in distributions?Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com2tag:blogger.com,1999:blog-7021667619473970091.post-49391560878226686492009-07-03T20:49:00.000-07:002009-07-03T21:02:49.237-07:00If this isn't an adventure, I'm not sure what is..I named this blog "adventures in perl" because of the work that I do, being in Perl, and the fact that it's fairly zany stuff compared to my previous work experience. Here we go.<br /><br />I have applications that start up in the morning, and shut down in the afternoon. They log very important data throughout the day detailing their actions. The log files are gargantuan in size (think TB), every day. We are forced to use LZMA to compress these suckers down so we're not in the business of inflating Seagate's stock price ;-) ... Anyway.. The compression starts shortly after 6pm, when a "spare" system mysteriously crashed, causing one of the pre-req ssh calls to hang. (our engineer forgot to put a timeout wrapper, or put a timeout argument on the ssh call).<br /><br />The script "unstuck itself" the next morning, between me troubleshooting why the logs weren't transferred, and getting IT to fix the machine that crashed. So, the program went ahead and lzma'd all the log files for the current day, instead of yesterday.<br /><br />I sat in horror as I realized that our programs were now writing to deleted files (lzma is kind enough to remove the file after it compresses it). Most of our programs shut down immediately at 4pm, so we had to act fast. <br /><br />The solution, ended up being a simple perl script, that interrogated "lsof" for deleted files in our log directory, on all of our machines, and simply opened a file handle to the /proc/pid file descriptor matching the file in question. This incremented the "open" count, so even if the program that was writing to it went away, the file would not be marked for deletion.<br /><br />We had a hook on our script that allowed us to signal it to copy files in proc back to the file system, after we had cleaned up the lzma files that were already there. The best part, we got to use the totally underrated "cluster ssh" to take command of all of our servers at once to fix the problem one time, for all of our machines.<br /><br />Problem, solved, the program was easy to write, easy to verify, and performed perfectly on the first try. Hooray Perl!Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com10tag:blogger.com,1999:blog-7021667619473970091.post-41992689832894112862009-06-20T05:46:00.000-07:002009-06-20T07:39:01.567-07:00Benchmark.pmTim Bunce++ !! Benchmark.pm is one of the great libraries that separates Perl from other dynamic languages. It's my favorite module for determining the performance of code snippets that run external from my full application environment.<br /><br />Sometimes, you tend to need to know what your response time is at given rates of input, so you can know your boundaries on maintaining a specified level of response time. (A webserver's response time to a dynamically generated request for example). Averages, rates, etc, tend to hide the fat tails on either end of the response time spectrum (of a given rate).<br /><br />Taking your result set, and looking at from a percentile perspective gives you the fat tails, an idea of what your median execution time is, and it allows you to more easily compare two different rates (say, 100 page requests per second, vs 1000 requests per second).<br /><br />In my world, it's how many quotes, or orders per second, and every microsecond counts. Finding a fat tail helps us expose design flaws, technical limitations, or simply algorithms that don't scale terribly well.<br /><br />So, to summarize...<br /><br />Benchmark is an awesome tool for comparing snippets of code.<br />Calculating percentiles is a great way to understand how a system is capable of handling varying levels of load, and how "fat" the tails are to understand a systems capacity.Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com0tag:blogger.com,1999:blog-7021667619473970091.post-43421340440536781752009-06-18T19:50:00.000-07:002009-06-18T20:07:53.757-07:00Why Parrot is important, or not..http://www.linux-mag.com/cache/7373/1.html<br /><br />Here's the summary that I got from this...<br /><br />1. Parrot is neat, you can write languages very quickly and easily.<br />2. Parrot is a register based VM, which is better than a stack based one.<br />3. Concurrency is hard, Parrot isn't mentioned as being part of the solution, but if we ever figure it out, why not do it in Parrot so we don't have to do it again and again going forward?<br />4. Parrot is going up against Microsoft's CLR/DLR, and Sun's JVM. Parrot is forcing their hand to make improvements. <br /><br />I feel like reading between the lines there is a defeatist attitude in the last three paragraphs, that MSFT and ORCL will just hulk smash Parrot with $$ and Parrot is one big academia project that won't end with a system capable of generating production level code. Seriously, that's ok though, they're doing all this for FREE, they don't owe me anything. I'm just thankful for Perl5, my entire livelihood is based on it, and it's an honor to stand on the shoulders of giants to do what I do.<br /><br />I've been using what little free time I have to try to learn Perl 6 and Parrot (not exactly easy with our first baby arriving a little over a month ago). I'm not sure I want to invest, literally my future into it anymore. Hence my intrigue over Vala. Being a Perl/Java programmer in the past has got me pretty far, but seeing how I hate Java, I'd better find a decent replacement, and I'm not sure Parrot/Perl6 is it.Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com0tag:blogger.com,1999:blog-7021667619473970091.post-86679144117150607402009-06-18T19:40:00.001-07:002009-06-18T19:50:07.908-07:00Vala?! Genie?!Ok, let me be totally clear. I loathe, and detest java, in all forms. I love Perl. The dynamic nature of scalars, the quick and easy lists and hashes, it's all just too good.. The bonus is "strict" and "fields" that give you that warm fuzzy compiler error, instead of having to hunt issues down with endless unit tests (and even then, you'll probably never find them all)...<br /><br />But, Perl isn't C++, and well, coding in C++ is about as much fun as pouring gasoline in my eyes. I NEED a language that is faster than Perl, but isn't C or C++, and for the love of god don't tell me about some VM that has magical powers. (I have more to say about Allison's post here in a second).<br /><br />Sooo, a guy in my office showed me a link to Vala. Wow...<br /><br />Reference counted memory management..<br />Braces / semicolons based syntax (or python, if you prefer, use Genie)<br />Compiles down to a binary (no virtual machine)..<br />It's only pre-requisite is glib..<br />Lambda expressions..<br /><br />Wow wow wow.. So, I give up my untyped scalars, to get C level performance, no more ridiculous XS calls, and I get even tighter compile time safety?! Where do I sign up?Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com1tag:blogger.com,1999:blog-7021667619473970091.post-22629931767236810962009-05-31T13:13:00.000-07:002009-05-31T13:22:11.565-07:00The promises of Parrot?I own both Parrot / Perl 6 books. I'm totally aware that they're totally out of date now, but I'm curious how much of the "original" ideas are going to hold on?<br /><br />1. If you have a "Python" library, can you compile that to parrot bytecode, and then import that into Perl6 transparently and use it transparently in your Perl application?<br />2. Is the garbage collection system going to support a fallback "reference counted" system? Perl seems to have a "constant" burn (when it comes to memory management) that doesn't hiccup like Python, Java or .NET seems to have (without some tuning of course).<br />3. Will we ever be able to truly "compile" a Perl application into a binary (without statically linking the entire Parrot system into the executable?) <br />4. Guys that I work with claim that Parrot will fail to "be the best" because it's not based on LLVM, and because everyone else (Google, with unladen swallow) is playing the "Not invented here" card, instead of helping out Parrot. Competition is good, but it seems that Parrot / Perl has NO friends out there, did somebody burn some bridges or something?Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com2tag:blogger.com,1999:blog-7021667619473970091.post-77397347855329634832009-05-31T11:14:00.000-07:002009-05-31T11:21:49.295-07:00High precision timestamps in Perl5/Perl6?Why does Perl5 and Perl6 chop off a digit of precision on a high precision time call?<br /><pre><br />use strict;<br />use Data::Dumper;<br />use Time::HiRes qw( gettimeofday );<br /><br />print gettimeofday() . "\n";<br />printf("%f\n", scalar(gettimeofday()));<br /></pre><br />Produces:<br /><pre><br />1243793974.02361<br />1243793974.023704<br /></pre><br /><br />And, in Perl 6...<br /><pre><br />say time();<br />printf("%f\n", time());<br /></pre><br />Produces:<br /><pre><br />1243794052.38889<br />1243794052.391031<br /></pre>Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com2tag:blogger.com,1999:blog-7021667619473970091.post-57695082223348871942009-05-31T11:04:00.000-07:002009-05-31T18:54:55.672-07:00Perl 6!I feel bad bugging people for help with Perl 6, especially when you're simply trying to compile the damn thing. Chromatic goes on and on about how doing lots of releases is really important for something to be viewed as "alive" and "progressing". I dunno. I waited with glee for the Parrot 1.0 announcement to go out, and then fumbled until this last week to get Rakudo running on my mac. No big deal, I'm an early adopter. I believe in Perl, and I know that it is going to rock when it's finished, so dealing with the headaches to get it set up are worth the trouble. But, not everyone is like me.<br /><br />Anyway, I just wanted to point out this one VERY cool thing (in my eyes) that was like the second or third test program I wrote.. Heck, I'd love to make this into a test for the test suite if it isn't covered... (it addresses a weakness that Perl 5 had, that was documented)..<br /><pre><br />my $foo = "1f9";<br />$foo++;<br />say $foo;<br />$foo--;<br />say $foo;<br /><br /></pre>This spits out...<br /><pre>1g0<br />1f9<br /></pre>A perl 5 equivalent will say...<br /><pre>2<br />1<br /></pre>But Perl 5 supports a simpler increment system (sort of)...<br /><pre><br />$foo = "f9";<br />$foo++;<br />print $foo . "\n";<br />$foo--;<br />print $foo . "\n";<br /></pre>This dumps out:<br /><pre>g0<br />-1<br /></pre>Hooray Perl 6!<br /><br />(I found the test for this, it's S03-operators/autoincrement.t, it doesn't cover the "1f9" case, which doesn't work in Perl 5). I'll see if I can get commit bit access to this test next week!Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com0tag:blogger.com,1999:blog-7021667619473970091.post-56881332129765299992009-05-31T10:36:00.000-07:002009-06-20T16:30:06.726-07:00My heretical love for compile time safety...I have to admit, as a first blog post, this one may not be the best to introduce myself. I program in Perl, every day, mostly for work, but it's cool work none the less. I work in the financial industry, with nearly 13% of the US Stock market coursing through my models . We use lots of Perl to get lots of things done. Having only really seen Perl used in a web environment, I was blown away to see what Perl is really capable of.<br /><br />I have always been a "use strict" guy, like many of you who would read this I have the t-shirt from thinkgeek with that on the front. My current position introduced to a module called "fields". It took me a while to appreciate it, and it was really only after I started writing code where I wasn't using it did I realize how awesome it is.<br /><br />The point of my post is, quite simply that Perl fills a niche that no other scripting language (that I have seen) is capable of doing. It provides compile time safety on variables, as well as attributes of objects. People have accused me of having flimsy testing suites, and my only reply to that is that my codebase is so incredibly big (and most of it inherited from previous engineers) that we MUST know about the possibilities for a mistake, and are willing to pay any price to find out before we deploy. This simple validation of any changes we make drastically reduces any errors, and provides a cushion for any code path not covered by a regression or unit test.<br /><br />I'd really like to be able to have compile time safety of methods, as well as their arguments, the closest way to seem to be able to do this, <a href="http://search.cpan.org/%7Eswalters/typesafety-0.05/typesafety.pm">typesafety</a> doesn't work at all for me, on my mac or on a linux box. I'm told that Perl 5.10 (which we haven't upgraded to yet) has a new method resolution system, I'm hoping there may be a way to override the whole thing and disallow sub-routine generation at runtime so I can do compile time checks. It may be just one big pipe dream, but we'll see.<br /><br />So there you go. Fields is awesome, and it looks like this whole Moose thing kind of glosses over this, so I imagine that Perl 6 will as well, (if I'm wrong, please point this out!). Hash::Util::lock_keys is not the same. I want to do "perl -wc" and see my errors, right now..<br /><br />Example:<br /><br /><pre><br /><br />use strict;<br />use warnings;<br />use Hash::Util qw( lock_keys );<br /><br />my %hsh = ();<br />lock_keys(%hsh, qw(x y z));<br />$hsh{'A'} = 1;<br /><br /></pre><br /><br />This passes "-wc" with no problems...<br /><br />We prefer a compile time failure to occur, like this:<br /><br /><pre><br /><br />package FieldTest;<br /><br />use strict;<br />use warnings;<br />use fields qw(a b);<br /><br />sub new {<br />my FieldTest $self = shift;<br />unless (ref $self) {<br /> $self = fields::new($self);<br />}<br />return $self;<br />}<br /><br />package main;<br /><br />use strict;<br />use warnings;<br /><br />my FieldTest $tmp = new FieldTest();<br />$tmp->{'c'} = 'whatever';<br /><br /></pre>Ryan Dietrich (dextius)http://www.blogger.com/profile/11943821568720043413noreply@blogger.com0