fREWdiculous!
10 Aug
Today we had our Dallas.p6m meeting, which was a lot of fun as usual. This meeting was especially interesting because Rakudo * was released since we last met. In the meeting I discussed my little project to port Log::Contextual to Perl 6. First off, here’s the code.
There are plenty of positives and negatives to Rakudo *. First the positives!
It’s pretty cool that the tests actually pass! Not all of them of course though…
People may not take this seriously, but . is better than ->. Seriously. Plus there are types etc.
So…. this may or may not be a feature. It works for the simple stuff. Is it as flexible as Sub::Exporter?
In Perl 5 if you want to define a private method you use _ as a prefix. First off that’s an idiom, not part of the language, yadda yadda yadda. More importantly, it’s not really private, just marked as “don’t use this.” With Perl 6 it’s (almost) truly private. Nice.
A lot of people are gonna hate this one; but it’s meant to solve the “print (5 + 6) * 12″ issue. It has a lot of other implications too, which again, are going to bother people. Now I can name a method log-debug instead of log_debug or lord forbid logDebug. Nice!
Arguably the best feature of Ruby. Perl 6 does it now. Neat!
This is hard for me. In Perl 6, a block (denoted “{ … }”) should take zero arguments unless you explicitly state otherwise (with $^a etc.) You may not notice that in most places, but Log::Contextual uses that kind of stuff constantly. I expected it to be like Method::Signatures::Simple which just sets values to undef if they are not passed. Anyway, I can live with this, it’s just different.
This is more like Javascript and Ruby, both of which I’ve used with joy, so I’m sure it will be fine. The gist of it is that when you do:
1 2 3 4 | sub foo (@bar, $baz) { ... } my @biff = 1,[2,3]; foo @biff; |
You will get an error because @biff binds to @bar and $bar is not set. If you want to use an array for arguments you have to do “foo |@biff”. Much nicer than javascript’s apply, and the same as Ruby’s *.
This is not surprising at all. Not even really a complaint, but must be noted. To run the entire testsuite for Perl 5 takes 1.5 seconds. To run a single test for the Perl 6 version it takes more than 10 seconds. I learned in the meeting that I could precompile my modules and save a lot of time; like, three orders of magnitude difference.
Again, this is expected. Still annoying. Features I miss are lack of temp (which Patrick pointed out that I can almost replace it with dynamic variables, and soon I will be able to all the way), lack of caller, and write access to the symbol table.
My main example is that in Perl 6 undef == Any(). Patrick explained it. It makes sense. It’s still weird.
I couldn’t figure out how to get Roles to work. I’m not really sure how it is supposed to work. Am I supposed to use the role in the class that “does” the role? What about the code that is checking if it “does” the role? I thought I tried all permutations. What a hassle.
There are subtle differences between Class::MOP and Perl 6′s MOP. Do not assume that they are the same. You will get bitten. On the other hand, it has a great shortcut! Perl 5: $class->meta->foo. Perl 6: $class^.foo.
Those are the major issues I noticed.
If you are interested, by the way, Log::Contextual has three major features that you might like. First, it returns the arguments you pass it, so you can use it in the middle of subroutine calls and whatnot. Next, it has convenience methods for automatically printing out stringified data structures. Nice! And lastly, (but arguably the whole point) is that it has a great interface based on lisp-y principles. I really should give it it’s own blog post at some point…
10 Aug
One of the first projects I did at work was to make a web/javascript based interface for a piece of hardware that we sell. The machine is very underpowered so pushing a lot of the complexity to the client makes sense. It was a great project and is one of the few that I haven’t had to make modifications to since I finished it nearly two years ago.
Well, it turns out we are making a new version of the hardware and I have to add a ton of options to the UI. That is pretty easy in general, but first I have to get the app up and running. There’s NO WAY I’m going to flash the firmware every time I need to make a change to the javascript. What do I do instead? Mock the hardware with Plack!
Here’s the code I’m using:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | use Plack::App::File; my $app = Plack::App::File->new(root => ".")->to_app; use Plack::Builder; builder { mount '/settings.htm' => Plack::App::File->new(file => "../Web Source/settings.js"); mount '/WebResources/resources/css/extall.css.gz' => Plack::App::File->new(file => "../Web Source/extall.css"); mount '/WebResources/resources/css/xthemeblack.css.gz' => Plack::App::File->new(file => "../Web Source/xthemeblack.css"); mount "/WebResources/$_.gz" => Plack::App::File->new(file => "../Web Source/$_") for ( 'extall.js', 'extprototypeadapter.js', 'harmony_config.css', 'harmony_config.js', 'prototype.js', ); mount '/' => $app; }; |
The first and second line make a basic file server which serves up all the images and whatnot. The rest, the mount commands that is, rearrange things so that instead of using our pre-gzipped files it points to my source files. That way we can leave the html static but I don’t have to waste time copying stuff all over the place all the time.
Awesome!
29 Jul
I am proud to announce a new release of DBIx::Class::Helpers. There are five major changes in this release.
First off, the latest release adds DBIx::Class::Candy exports. So if you are using DBIx::Class::Candy to define a result, certain methods will be imported into your namespace. For example, DBIx::Class::Helper::Row::SubClass will export a subclass subroutine into your module. Not huge but nice nonetheless.
Next up, we have four shiny new components. Two are ResultSet components and two are Result components. One of the two ResultSet components was originally going to be in the core of DBIx::Class, but I decided to make a helper first to ensure that we iron out the details before we release it in core. That component is DBIx::Class::Helper::ResultSet::RemoveColumns. It does exactly what it sounds like. With it you can do
1 2 3 |
and the id column will no longer be selected in your ResultSet. I am sure that it has some quirks, but I am not sure what they would be till people use this. So have at it!
The next component, DBIx::Class::Helper::ResultSet::AutoRemoveColumns, is based upon RemoveColumns. Again, the name should make it clear what it does. Currently it removes typically large columns by default, like text, blob, and the like. See the docs for exactly what it removes. (Note: later on I hope to add a component that adds lazy columns as detailed in ovid’s post here. Ovid if you are reading this I can’t comment on your blog.)
Next up is a fairly simple component, DBIx::Class::Helper::Row::StorageValues. It gives you access to the last known stored value of a column. For example:
1 2 3 4 5 | my $foo = $resultset->search({ name => 'frew'}) ->next; $foo->name('frioux'); # prints "frew" say $foo->get_storage_value('name'); |
Building upon that we have my favorite new component: DBIx::Class::Helper::Row::OnColumnChange. This module adds powerful hooks for calling methods when a column has been modified. If you enable StorageValues for the column you hook into you get to look at the old value and the new value, which is pretty cool. There are three hooks: before_column_change, around_column_change, and after_column_change. It automatically takes into account values changing because of accessors as well as by the arguments passed to update. Also note that it allows you to tell it to wrap the call to update and the column change method in a transaction so that you can safely do things to other tables in the method. Anyway, enough talk, here’s a small example:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | __PACKAGE__->add_column(relationship_status => { data_type => 'varchar', length => 30, keep_storage_value => 1, }); __PACKAGE->before_column_change(relationship_status => { method => 'happy_times', txn_wrap => 1, }); sub happy_times { my ($self, $old, $new) = @_; $self->significant_other->update({ feelings => 'happy' }) if $new eq 'together' && $old eq 'apart' } |
So basically if relationship status changes from apart to togehter the significant other gets marked as happy, and all of this is done in a transaction, which is pretty awesome.
Anyway, hopefully this makes your job easier. Have a good Friday!
26 Jul
I have been using git more and more. I use it in all of my CPAN modules. I’m using git to the point where I expect everything else (that is, svn) to be just as powerful and fast. Unfortunately that just is not the case, and I’m still stuck with it for all but one project at work.. For example, the other day I wanted to find the last commit that my coworker made. With git it would just be git log –author wes -1. I couldn’t seem to figure out a way to do it with svn. Maybe I’m just dumb? Add on to that the fact that git log is mega fast but if you do svn log You Have Made a Mistake. Also the colors! Who doesn’t like the fact that git has colors out of the box?
To sum up the previous paragraph: I need to learn to use git-svn. Lets get started:
First off, you need to make a users file. At my company that’s pretty easy since there are like, 12 people who have commit access to svn. This is what it looks like:
1 2 3 | david = David B. <elduderino@hotmail.com> fred = Fred K Beckhusin <gnarlbot@hotmail.com> frew = Arthur Axel "fREW" Schmidt <frioux@gmail.com> |
Put it in a file named “users” in the current directory. All this does is substitute the svn names (on the left) for the git names (on the right.) Next up, check out your repository:
1 | git svn clone --stdlayout --authors-file=users svn://reposerver/foo/bar |
This assumes that /foo/bar has subdirs /trunk, /branches, and /tags. If yours is different you’ll want to do something like the following:
1 | git svn clone --trunk='/Developer' --tags='/Releases' --authors-file=users svn://reposerver/foo/bar |
Of course you might need to do some tweaking there.
Now, we have three other svn:externals repositories in our repo. This is the most ghetto part of all of this, and it’s probably just because I haven’t done the appropriate research. Again, if you know better, just tell me. (Normally with git you’d do this with a submodule, but we aren’t going to do that because we want to directly check the “submodule” out from svn so we can commit back easily. If you don’t know what a submodule is, ignore this
)
1 | git svn clone --stdlayout --authors-file=users svn://reposerver/svnexternal1 $to_name |
This will check out the svnexternal1 repo to a folder called $to_name. If you need to check it out to a separate subdir either cd into that dir or change $to_name.
You don’t want to check that into svn because your coworkers already have an svn:externals for that. Normally this would be done with .gitignore, but we won’t use that because your coworkers don’t want a .gitignore file in their repository. Instead you’ll use .git/info/exclude, which is the same thing but not inside of the repo. Just put $to_name on a single line in that file and it won’t show up in your available changes when you need to commit.
Speaking of commiting, how do you commit? Normally your workflow should be the way it is with git. You commit often and when you are ready for a feature to go to the team you push it out. I usually rebase and clean up commits before I push, but that’s up to you. The main difference is that you don’t do git push … Instead you’ll do
1 | git svn rebase && git svn dcommit |
git svn rebase actually checks out the new changes from svn and puts them in your repository before the changes you’ve already committed. If there are conflicts you’ll have to deal with those of course, but otherwise it will just pull in the changes and then use dcommit to submit new changes. You should not have any uncheckedin changes when you do this (it will complain if you do) because dcommit actually does a different kind of rebase after checking in changes. It changes your commits to include the svn id so that the git commits match up with the svn commits.
In general that’s all there is to it. At some point I’d like to do a post about how I use git rebase fairly often in my workflow, but this I think is a lot more important. Oh and here are some cool new git features I learned today. Enjoy
22 Jul
Yesterday I released a new (major version of) Devel::Dwarn, or what is technically Data::Dumper::Concise. But those in the know call it Devel::Dwarn.
If you did not already know, Devel::Dwarn is sugar + good defaults for Data::Dumper. Check it out. Drool. Use it.
Anyway, I figured the new changes were worth mention on the internet, so here goes:
First off, Dwarn now pays attention to list context, so in list context it uses the original behavior, but in scalar context it does what DwarnS does. One of my coworkers got bit by the Dwarn vs DwarnS distinction so much that he only uses DwarnS now. Hopefully this will remedy that issue.
Next up is that Dumper (and also Dwarn because it uses Dumper) no longer returns an object when passed zero arguments. If you used that I’m sorry; but it just bit most of us when we tried Dwarn(@foo) and @foo was an empty list. Sorry, it’s gone!
Last, is the brand new DwarnN. DwarnN is a neat debugging tool which will label your output by the variables passed in. So if you do DwarnN $foo it will print ‘$foo => ‘ . Dumper($foo). Not world changing, but still very helpful!
Hopefully this will ease your job that much more!
20 Jul
Over a year ago I read this blog post. To be honest at the time I thought it was mostly silly and I still feel that way. The things that are important to me in an ORM are capabilities, not subjective prettiness of code. But, I also get tired of typing repetitive things, especially __PACKAGE__->. That’s just too many shift keys! So after working on a few different modules and accruing various bits of knowledge here and there I learned what I needed to to create a sugar layer for DBIx::Class that doesn’t throw the baby out with the bath-water.
I am proud to announce the initial, development version of DBIx::Class::Candy, which should be coming to a CPAN mirror near you very soon. If you just can’t wait, use cpanf to get it right now. The basic gist of it is that you can use:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | package MyApp::Schema::Result::Artist; use DBIx::Class::Candy; table 'artists'; column id => { data_type => 'int', is_auto_increment => 1, }; column name => { data_type => 'varchar', size => 25, is_nullable => 1, }; primary_key 'id'; has_many albums => 'A::Schema::Result::Album', 'artist_id'; 1; |
instead of
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | package MyApp::Schema::Result::Artist; use strict; use warnings; use base 'DBIx::Class::Core'; __PACKAGE__->table('artists'); __PACKAGE__->add_columns( id => { data_type => 'int', is_auto_increment => 1, }, name => { data_type => 'varchar', size => 25, is_nullable => 1, } ); __PACKAGE__->set_primary_key('id'); __PACKAGE__->has_many( albums => 'A::Schema::Result::Album', 'artist_id' ); 1; |
There are a few other features, like having it turn on 5.10 or 5.12 features, use a non standard base, and more. Check it out now!
26 Jun
This year Rob Kinyon and mst convinced me to do some speaking at YAPC. I ended up doing three forty minute talks. The DBIx::Class one was certainly the easiest, but also the one I was least invested in. I didn’t write DBIx::Class and it’s a big enough project that the slides nearly wrote themselves.
I also did a talk on DBIx::Class::DeploymentHandler. I am a little frustrated with how this talk went down. I am confident that DBICDH is an excellent piece of software that can do some really cool things and I kinda botched the end of the talk (very abrupt.) I wouldn’t call the talk a failure; it had a great turnout and at the very least I got to discuss features with jnapiorkowski, which was fun.
My third talk was about DBIx::Exceptions. It was hard for a couple reasons; first off DBIE isn’t actually done yet. That certainly is not conducive to talking about something. Second, what it ultimately does really isn’t that complicated. The module is almost entirely a function of doing some research. So while I think that the subject is good and interesting, I don’t think it warrants a whole 40 minute talk. I actually had a long discussion with Rob about exceptions in general and he strongly supported the point of view that exceptions in any language are fundamentally flawed. I’ll turn that into a blog post at some point.
I finished all three of the talks in less than forty minutes; I think that was a combination of me talking too fast (DBIC + DBICDH) and not actually having enough content (DBIE.) I would have done better were I less nervous, which should be less and less of a problem as a I practice technical speaking more. I actually did a lot of presentations in college and rarely had these issues, but in college I almost never spoke about software I wrote and my talks were usually from 10 to 20 minutes long. Another thing that I feel is important is that I need to try to add humor to my talks. The talks that are the most engaging are also the ones that are entertaining. I’m not sure I how I could work in jokes etc, but I need to try to do that next time.
In other news, I’m pretty worn out in general from YAPC. I just need a break. So while I will do bug fixes and whatnot for my existing modules, and I still hope to release DBIx::Exceptions very soon, I’m going to try to chill out for about a month before taking on any of the other large ideas I have in mind for the future. Or at least I won’t start them on purpose
23 Jun
So I just got back from my second YAPC. Again I had to leave early, but not as early as last time, so that’s good. Instead of summarizing every single talk I went to, I’d like to highlight some of my (most and least) favorites.
I can’t help but follow this since I see Patrick fairly regularly in our Dallas.p6m meetings; which is really half Perl 5 and half Perl 6. NQP is an amazing bootstrapping language for Perl 6 that is actually already self-hosting (written in itself!!!) and can do a lot of neat things. And of course Patrick is an excellent and humble speaker, which always helps.
Take a look at the slides (linked to above, page up and page down for next and prev slides) for more information.
For a language as minimal as they could get away with it’s extremely pretty. Note: For all the talks mentioned here, slides != talk.
Plack is very cool tech, even though Perl is late to the concepts it brings us. The cool thing about the talk was that it starts off really slow and then ramps up to some really amazing middleware that just blows my mind. Miyagawa was an excellent speaker and had lots of fun little jokes in his talks too.
I was told to go to this talk by ribasushi with the sole idea of stealing ideas for DBIx::Class. I was generally unimpressed with the ORM part, but Fey is far better than SQL::Abstract it seems like. Rolsky is very adamant about having no magic in his core, which is fine, but it typically means baseline code will be ugly. It’s certainly a trade off. He has a really cool autojoin feature, which I envy but also know that ribasushi already wants to implement that to an extent. Our $rs->as_query is cool, but he has something like that for EVERYTHING, which yields some interesting results. Of course this is due to his thoughts that pretty stuff belongs in a sugar layer. He has much more powerful relationships, which I envy for now but I also know that we have a branch in progress to give us arbitrarily complex (???) relationships. It seems like he has a global schema, which is too bad, but that’s just how things work sometimes. He wants to keep per db stuff out of the core, which I can certainly see being a good thing, but I also think it’s good that we try to keep all of our per db code up to snuff, so theres a tradeoff there.
Overall I thought rolsky was very honest about the fact that Fey (and Fey::ORM) is about doing things differently due to taste and that’s completely fine. I definitely envy his SQL generation code, but I’d rather SQLA2.
Look around at some docs on AB testing. The stuff they did with this was amazing. Forget hallway testing. This is where it’s at for usability.
Ever want to look up how //= works? Not easy. Check out perlopquick. Awesome stuff for the future of core docs.
For this talk I have to give a little bit of background. This year it was attempted to film every single one of the talks unless the speaker explicitly said not to. Cameras et al were paid for by the conference’s budget. Of course, cameras are not all you need. You also need someone to run the cameras. It turns out that ONE MAN (his name is Krishna) did ALL of that for all five tracks. Of course the videos won’t be perfect, but if this becomes a trend it would be a great thing for all of perl.
The speaker of this talk, like probably 33% of all the speakers in general, had technical difficulties getting his mac to work exactly how how wanted with the projector. He (reasonably) got frustrated at this and the wasted time it caused. What bothers me is that krishna was setting up the camera (and mic) as he did in every room every morning and walt said, “Why are you even here?” to krishna, presumably thinking that he was staff of the college (which is of course a great reason to treat a person poorly) and continued to lash out complaining about his technical difficulties. I guess to put a positive spin on this I got to know krishna better for it and I think we all owe him a beer or curry or whatever for all of his hard work (and apparently taking abuse) for doing WAY too much A/V for one person.
The talk was ok.
This was mst’s Iron Man forfeit talk. Watch the video, it’s hilarious. I’m not sure much more can be said
I heard about perl5i last year and I thought it was neat. Now I think it’s excellent enough that I might use it in code at work. One thing I think is very good about it is the fact that you must use a version number when using the module, because it is expressly backwards incompatible. Take a look at the module. Very fun.
This basically looked at the psychological term called “framing.” The gist of the talk: when you say “Perl is not dead” people see “perl is dead.” So instead you have to completely reframe and say “Perl is alive” etc. We ended up all yelling perl is alive and scaring prospective students that were visiting Ohio State. Awesome.
This was a talk by ology about (duh) music. Very cool stuff. I wish I could have talked with him more than I did for the few minutes that I did, and especially I wish I had discussed the music stuff with him. Unfortunately he ran out of time in his talk, but what he did say was getting very cool
This was a hilarious talk by a man who moved to the US from Japan and learned some english with perl. It focused on Lingua::EN::Inflect, using CPAN as a dictionary, and adorable daughters.
Not really a talk per se, but still a fun time. Apparently the auction usually takes hours, but this only took 1.5 hours, so not really that bad, and still a lot of fun. I got some O’Reilly coasters (beer mats for you brits) and wes got the new Effective Perl book + autographs. Very cool.
This talk was interesting in structure. It started off fairly slowly but got super cool as it built on itself. It made me want to start writing CLI apps. The fact that it yields such a nice API makes it hard for me to justify why I like the way that catalyst does it’s dispatching (all spread out) but I do think that different ways of doing things are valid. I would love to write some kind of text adventure game with this. Maybe I’ll use it to create a Perl tutorial game?
Again, this was Patrick. This talk makes me want to start writing my one off scripts in Perl 6. Unfortunately some of my more interesting “one off scripts” involve creating a DBIC schema and shoving data into an sqlite database so that I can get a feel for my data. Either way, check out the slides, very cool stuff. Also note: I downloaded and installed rakudo in the talk and actually played with it. It’s been a while since I’ve done that and I assure you it’s only gotten easier.
All in all it was a great conference. I liked it better than last year despite the stress of three (supposed to be) forty minute talks. I’ll discuss that in my next post
10 Jun
Do you remember when you first realized that you were not the only person with a perspective in the world? I do. I was 5ish and I remember looking into the car to the left of me and seeing another person looking at me from their respective car. I remember thinking, “This is not what it is like from their point of view.” I distinctly remember reevaluating things all day that day. I am sure that I was still just as selfish and childish as I was before that moment, but it certainly changed my point of view.
Major features this has over DBIx::Class::Schema::Versioned:
So try it out today! I am looking forward to getting bug reports soon
Oh also, if it does not quite do what you want…
PATCHES WELCOME!
3 Jun
I am so happy to announce that DBIx::Class has migrated to git!
If people latch on well, this should benefit is in a number of ways. The first thing is that most people should appreciate is the ability to check in to source control without needing to commit to the remote repository. Not only does this make things way faster, it also means that you can work sanely offline. A lot of people did this before with SVK, but SVK is slow and a hassle (I think) to install and setup.
Another thing that this should help is our history. I don’t mean to point out a specific person, I did this all the time with svn (it’s just the nature of the beast,) but take a look at some of these commit messages. The SVK merge messages are pretty obnoxious, but that’s not what I’m referring to. The ones that bother me are the: “Oops,” “Typo,” “Thinko,” etc. With git those can be cleanly squashed into another commit. In fact, I would recommend cleaning up your history before you push every time. This is how I do that:
1 | git rebase --root --onto master --interactive |
That will rebase your current branch (all of it) onto master, and give you an editor that will let you fix commit messages, merge commits, and more. If people do not do this I fully intend to do it myself before I merge a branch in, if I do. And that brings me to the next point which we shall discuss.
We toyed with the idea of setting up git such that everyone would just use github or gitorious or whatever and ribasushi and I would be in charge of merging remote branches into the DBIC master, but mst veto’d the idea in favor of a more communal approach. Basically the workflow we will use looks like the following:
A note about merges, don’t merge master into your branch. It makes for yucky history. Instead, rebase your branch onto master. Currently the thought is that anything except for master can be rebased. Of course if you and another dev are working in the branch you might want to keep that to a minimum, but at the very least you should be rebasing to squash silly commits before you push, and then when you do the final merge into master you should rebase first, so that history remains sane. Of course, the best time to rebase to fix silly history is before you push, and the best time to rebase to make it so that you are fastforwarding master is right before the final merge, so try to only do that then.
At some point I plan on writing a DBIx::Class::Manual::Contributing in the spirit of Moose::Manual::Contributing, but ours will be significantly more lax. In the meantime, just swing by #dbix-class, get your commitbit, and help out!