Apr 28, 2010

Dist::Zilla vs xenoterracide

I solved my problem with Dist::Zilla. If you agree with me that you should be able to install from your git repository, without requiring your users to have Dist::Zilla installed here's one way of doing it.

First install Dist::Zilla::Plugin::CopyTo. Now Edit your dist.ini. Most people probably use one of the Dist::Zilla bundles. Assuming you use Basic here's what you do. Now as you can see we use GatherDir to get where the source should come from and CopyTo to tell additional places where the output of the script should be sent to. It will still send to the default directory, that's ok, you can just ignore those files. add . to your repo (making sure to add the default generated location to your ignore list) and commit. now if dzil changes any of these you can see it.

If you wanted to with git you could use a git-new-workdir and another branch and copy to it and commit this stuff to a different branch. I haven't found another way to do it in a seperate branch yet, although someone said it's possible.

P.S. 1
If dzil ever gives you some vague error about some util file... run dzil clean I don't know why it was doing that to me occasionally through all this but I spent like 8 hours thinking my config was screwed up when the directory just needed to be cleaned.

P.S. 2 Thanks to rjbs for putting up with my asininity while I asked a lot of questions and ranted.

P.S 3
My stuff is 99% working now... I just have a problem where my licensing is wrong :( I've set it to Perl_5 but it really should be GPL3 and Artistic2 (or whatever those are in Software::License).

Apr 27, 2010

My new Love/Hate Relationship with Dist::Zilla

Dist::Zilla is a great release tool, code generator, and it just plain takes the boring part of doing a release away from you.That having been said, it does, imo, horrible things to your source repository. "But, Caleb, it cleans up your source repository you can remove a lot of excess stuff you don't really need to be storing there". Well... I disagree, to the point that I've used every explicative in the book to express my displeasure. Let me explain why I disagree.

First let me explain my use cases. I have only one package on CPAN, Template::ShowStartStop and it's relatively simple to the point that Dist::Zilla is almost overkill (but I still find it nice). I also maintain a sizeable portion of CPAN on Arch Linux's AUR. In addition to standard CPAN Packaging for my own package I created a -git package which allows me to install directly from my source repository on Github. That worked wonderfully well until I started using Dist::Zilla (note: I haven't gotten a poorly working (read hack that's buggy) version now).

So Dist::Zilla is great for CPAN, no problem for normal downstream packages, but makes things more painful for Version Control Users. "But Caleb, it does nice things for me for version control". Yes it does, but I think it also has some consequences that people don't realize. If you know how Dist::Zilla works pretend that you don't.

Look at my repo What License is my code licensed under? usually this is in the COPYING file. There's no COPYING file there. How do I install it? No README either, oh and the module isn't complete as is things like version are stripped so Dist::Zilla can generate them for me. This list goes on and on all basically leading back to my issue. Why does Dist::Zilla have to take these things out of my source repository?

The answer was... you wouldn't store .o files in your repository would you? why would you store these generated files... oh I dunno... because someone shouldn't have to install Dist::Zilla just to use my latest git? and they aren't like .o files because those are binarily specific to a lot of things and won't be useful on most other machines, unlike these files.

Let's say Dist::Zilla has a bug in what they generate for code. They fix it, I update, all is good for me. Someone else who hasn't updated Dist::Zilla downloads the code and builds and hits the bug... they complain to me. I explain it to them, they update Dist::Zilla, they're happy, I'm happy. But we could have avoided this, if I stored all the output in my repo they'd never have to worry about Dist::Zilla.

So I've been told this will never be fixed because they don't want to clobber the existing files, plus the whole... these are like .o files, thing. Ok, clobber == bad. So how could we fix it so I'm happy? and everyones happy. We should a directory src shall be the source of all non generated code. Much like when working with compiled code you have a src directory for source files and a directory for output. the lib that's still here will be the final generated lib. All the top level files will also be generated. Only the stuff in src is what should be worked on. And the generated README will give all these wonderful instructions that will now be presented to users visiting the github repo. And when I'm writing a -git package I won't have to include any dzil instructions because I don't need to generate this code all the time.

and you know what? if people don't want to store generated files in there vcs they can always use something like .gitignore. So everybody should be happy.

For backcompat just make it a configuration in dist.ini. We can have a [src] dir which could be . for those who want it the way it works now. and an [output] dir.

Will Dist::Zilla be worth this pain? I'm not sure.

Apr 25, 2010

cat that displays tabs at 4 spaces

So in the tabs vs spaces war I'm squarely on the side of use tabs. tabs have meaning. tabs allow people to set there editor's to whatever space display width their eyes are comfortable with as opposed to what yours are (e.g. you like 2 spaces I like 4). However, I've heard the argument what about when you cat the file, etc. Well it is actually a bit annoying... so let's fix it.

my requirements when I type cat foo if foo has tabs they will be displayed at 4 spaces, and I can still pass all cli options as I normally would to cat. To do this we're going to create a shell function called etcat()
I'd like to note, that in order for this to work you must use either an absolute path or a call to env cat because otherwise the shell will attempt to call cat as a recursive function. I put this in my .alias file and sourced it.

you can now put alias cat="etcat" in your aliases file, or run etcat. This is to protect you from any problems that could otherwise be caused by overriding cat in scripts you don't control (not that I'm actually aware of any for this function).

P.S. Thanks to @greybot on #bash for the incantation as I was having trouble with the "$@"

UPDATE:
changed name of function.

Teaching Perl - Week 2 ( part2 )

This part2 was prompted by Chromatic's post on state. I'd never heard of state before, and it's documentation is poor. Let's take a look at how state could affect our game.As you can see this allows us to make our $guess variable lexically scoped, meaning it's contained within the loop. This however generates some warnings: Use of uninitialized value $guess in numeric eq (==) at ./game.pl line 14. and if you enter non-numeric input Argument "l\n" isn't numeric in numeric eq (==) at ./game.pl line 14, line 1.. Both are completely fixable, but lets fix the uninitialized first.

So all we've had to change is adding parenthesis around state and assign it to a value. If we had used a my declaration it would reassign to 0 every time and we'd never match the $winning_num. But since state will only ever initialize once we don't have that problem. We still have our problem if we enter a character though, let's sanitize that input.
So in order to fix the 'not a numerical comparison' issue we check $guess to see if it's a digit with a regular expression. If it isn't a digit we set it to 0 which is an invalid guess anyways, but fixes the warning. This actually fixes two bugs. Before if you entered a letter it would tell you that it was too low (which I don't actually understand, because aren't characters > numbers? if someone on Iron Man could explain it in a comment.)

Apr 18, 2010

Teaching Perl - Week 2

Guess the Number

So our little game is exceptionally mediocre and not very fun. Head First Programming: A Learner's Guide to Programming Using the Python Language suggests we give the game player some help by telling them if the number is lower or Higher.

This game is a lot less challenging, and still not very good. So one one of the problems is it exits instead of letting it try till we get it right. So lets change that.

This one is going to show your students something they likely haven't seen before. An until statement. until is logically equivalent to while not or in this case you could write while ( $guess != 5 ) {...} and have it do exactly the same thing.

We've got some bad practices in this code it lacks useful comments and uses a magic number. Also the instructions aren't clear if you don't know how the program is written. Let's add that stuff next.
So this code is too simple for comments, but I've tried to show what I think some good ones would be. Usually 'novice' books say use meaningful comments but don't show any. Students then end up writing comments like # initialize local variable guess to 0. That's not useful the code obviously says that. Instead comments should say, what a larger chunk of is trying to do, or why it's doing it that way.

In Head First Programming: A Learner's Guide to Programming Using the Python Language the author uses the variable secret where I've used $winning_num because he ends up using a random number generator (we will in a moment), however, this is not a very descriptive name. $winning_num is a better name because it's more descriptive of what the number actually is. He also skips removing the 'magic numbers' step which is probably why the variable name used is poor.

So let's make the winning number random.

There we go... Now are number is random. ... ... ... notice the logic error yet? no? go read the rand documentation. Got it now? ok simply put this generates 10 total possible random numbers starting at 0, e.g 0-9. Our code isn't broken but it's not doing what we want. But the docs don't say how to generate a range... how can I do that? run perldoc -q random this will return perlfaq4 we're looking for How do I get a random number between X and Y?. That tells us how to fix it... our code should now look something like.

we could just put 10 in rand in this case but that's not as flexible. You'll also note I commented on why we did it that way. Kind of a way of making sure no one goes back to the other way, it also tells people why we did it this way.

If you've used another language you might ask, "Why not use a switch case?". Most instructors and books say "perl doesn't have a switch case". Even perl intro still falsely states that
"Perl has most of the usual conditional and looping constructs except for case/switch (but if you really want it, there is a Switch module in Perl 5.8 and newer, and on CPAN."
. That's even worse! Switch.pm has been in core for a while now... but is deprecated an you should NOT use it. since perl 5.10.0 perl has had a Switch statement, so let's rewrite our code using that.

Note the use of use feature 'switch'; make sure you use this instead of use Switch; which will use the now deprecated Switch.pm module.

You can shorten use feature 'say'; use feature 'switch'; to use feature qw(say switch);.

Beside's introducing switch/case this introduces the default argument $_ and smart matching.

You'll also note that I changed the algorithm but my comments didn't change.

As you can see TIMTOWTDI.

Homework

What else is wrong with our game? how could we fix it? How could we prevent the problem from being reintroduced? How can we be sure that our random problem is actually fixed? and make sure that it's not reintroduced? Can you think of any other ways we can write this program? or any other improvements? write the program so that it has 3 difficulty levels easy, medium, hard with ranges 1-10,1-100,1-1000 respectively. Blog these to Iron Man.

Optional: if you have Programming: Principles and Practice Using C++ have your students do Drill 1 from chapter 3 (obviously in perl not c++).

Teaching Perl - Week 1 - ( Part2 )

Padre - Perl IDE

Now let's install Padre the Perl IDE to give the students a nice development environment. There are instructions on the website, however, cpanp -i Padre should get the trick done since it is on CPAN In the future Strawberry will ship with Padre but that future isn't quite here.

First Program

Ok so we want to make sure that we have Perl installed correctly and since you're taking my advice I'm assuming that you've given your students access to 5.10.1 and may have 5.8 as well... So I'm gonna do this one twice. Have them create a text file hello_world.pl and add the following lines

#!/usr/bin/env perl

print "Hello, World\n";

Since I'm sure this is not your students first programming class this will be familliar to them. Explain the shebang (#!) line and note that it has no effect on windows. Now let's modernize it, using the say feature from perl 5.10.

#!/usr/bin/env perl
use feature 'say';

say "Hello, World";
note the removal of the \n and that use feature is a pragma that allows you to enable features that are newer in perl that weren't available in the original perl 5. Perl is a bit backwards about this, IMO. We should be using the newest version and features unless we specify otherwise, IMO, but that's not how it works, ATM. If 5.10 isn't available to you and your students just use print in future examples. I will be excluding the shebang line from future examples too.

Now let's expand hello world a bit. Have them Make it print

Hello, programming!
Here we go!
First thing is to make use of concatenation

use feature 'say';

say "Hello, programming"
    . "Here we go";  
This example is inspired by Programming: Principles and Practice Using C++ ( This is an excellent book and should be the textbook for BOTH C++ classes at Baker. I recommend all novice to intermediate programmers have a copy whether you like C++, or not, this book is excellent ). Please note that the . operator is in the front. This draws a programmers attention to it and notes that it's a continuation. See Perl Best Practices for more details on this.

Your output will be.

Hello, programming Here we go

That's not what we want! obviously say appends a newline to the end but doesn't help with long strings.

use feature 'say';

say "Hello, programming\n"                                                                            
    . "Here we go";  
Much Better.

Simple Game

Now let's up the ante a bit. Again not there first programming class, the following example is rewritten in Perl from Head First Programming: A Learner's Guide to Programming Using the Python Language which arguably should be the textbook for Intro to Programming. This is the first example that book gives in chapter 1 (but it gives it in python).
note: you can use < STDIN > but blogger screws it up because of the brackets. This code works exactly the same.

So now you can discuss: scalars, if then else statements,and readline. There are also two additional pragma's strict and warnings that you should tell your students to always use unless they have a 'good' reason to disable them (these have been there since the beginning).

So usually on the first night of class you're lucky to get past hello world. I think this is all doable. In 1 small program I just took you all the way to Chapter 6 in Perl by Example (3rd Edition) the chapter on control structures. Remember, this is not your students first class... you don't need to hold their hand through all this. Race through it so they can improve on it as the term goes on. Instead of spending 4 weeks (assuming a chapter a week) on if then statements you can now spend 10

Homework

Start a blog using whatever site you prefer (preexisting blogs acceptable) and add it to Iron Man. Do a first post that talks a little about you (blog can be anonymous). Include a copy of the simple game and what you think would be better about it. Also mention anything you'd like to do with, or know about, Perl.

Apr 13, 2010

Teaching Perl - Week 1 - ( Part1 )

Make sure you've read Part 0 first.

As I said before Baker provides a Linux server for the perl class. However, none of the students have had a unix class. So I advise touching on it and giving them a link to these tutorials if they want to use it, and a helping hand. The book also talks about ActiveState but this isn't the recommended way to do perl on windows anymore. Avoiding crux will prevent you from wasting a week or more on unix which is not what the class is about (my instructor failed horribly at this, and at knowing unix (or perl for that matter) well enough to cover it).

Strawberry

Strawberry Perl is the recommend open source binaries for windows these days and should work just like the unix ones. You should cover not only normal installation; but installing to their network drives (use portable edition), so they can have strawberry on any baker computer on campus; and to their flash drives (use portable edition), so they can take it with them to any computer running windows.

CPAN

Next you should mention CPAN. CPAN is the #1 resource in perl, if you need to do something, most of the time someone else has done it for you and it's on CPAN. Don't forget to mention search. and kobesearch.cpan.org.

local::lib

After talking about CPAN use it. Help your students install a local::lib esp if you're using the schools linux server which won't allow installs of global CPAN modules.

Task::Kensho

You'll want to recommend that students check out Task::Kensho which a CPAN module that lists all the best modules for common tasks, they may not be the only module for that task but they are the recommended ones. You could have them install them with cpanp -i Task::Kensho at this point or just recommend they look them over to see if they might find them useful. These are all probably ahead of where your students are at, but it never hurts to point useful libraries out early. Just tell them they can get back to them later. Note: local::lib is on Task::Kensho.

P.S. Week 1 will be multipart I have to leave now but I want to hit publish. coming next is how to teach them to do their first program the right way so they don't have to learn it twice.

Teaching Perl - Part 0 - Preface

This is my 2 cents on how perl should be getting taught at my school. My school's curriculum sucks in general across the board. But assuming I can't change what classes are taught, when and what prerequisites this is how I would teach perl given the current computer science curriculum.

Since people reading this are probably not familiar with the Fail that is Baker College (I would not choose Baker if I had to start again but credits don't transfer easily, so it was easier to continue on with it). Baker has 10 week courses, and with tech courses they are seemingly exclusively scheduled 6-10pm once per week. So this factors into how I'll lay this out.

Specifically for the perl class the curriculum provides the schools crux server which is running CentOS linux or something... (I'm not sure which distro it is atm). It does not have the prerequisite of Linux 101 though, and it's not in there curriculum. I don't believe it has any prerequisites other than intro to programming. It is a 300 level course, however. This means that most/all students in the course have probably taken a few C++, Visual Basic, and Java classes (there are about 6 of these classes at the 200 level and I imagine most have done at least 2 of the 6).

The book required at Baker is currently Perl by Example (4th Edition). I'd suggest telling students it's recommended but not required (If you won't get in trouble) in any event you and students shouldn't need to use this book at all, because a great book Beginning Perl is free online. Also the non book resources for perl are practically limitless and you should be encouraging the use of these. Some of them include
You should have a copy of Perl Best Practices. I've been told that you should read this with a grain of salt, that it's only like 50% accurate these days... but I think it's still a good place to start, and you can pick and choose what to use from it. You may also want a copy of Intermediate Perl For more advanced discussion on references and Object Oriented perl.

You may also want a good resource as a Linux CLI reference. This series of tutorials was recommended to me.

I will continue to post on the subject matter that I would cover each week, in this 10 part series (programmers count from zero ;) ). I may also discuss Perl by Example (3rd Edition) because that was the required book when I took the class, even though 4ed was out.

Update: Week 1 (part1)