No really.
My buddy Matt has been doing a comic book off and on for years. Some of the characters, or at least their names, are inspired by real people. It is pretty sweet.
Jay R. Wren – lazy dawg evarlast
babblings of a computer loving fool
No really.
My buddy Matt has been doing a comic book off and on for years. Some of the characters, or at least their names, are inspired by real people. It is pretty sweet.
a Cowboy You scored 5 Honor, 2 Justice, 10 Adventure, and 6 Individuality! |
Well pardner, the thing that drives you is a sense of adventure. You’re willing to play by the rules, but only so long as you’ve got open territory to cover and new frontiers to explore. You don’t need much and you don’t ask much.
Strap on your six gun and wear your Stetson proud. I think you’ll do just fine |
Link: The Cowboy-Ninja-Pirate-Knight Test written by fluffy71 on Ok Cupid, home of the 32-Type Dating Test |
http://www.npr.org/templates/story/story.php?storyId=5062814 I’m partial to the version done by PJ Harvey on Lounge-a-Palooza, but this one is awesome all by itself.
I sure wouldn’t have thought that Mel Torme would sing that tune. I also wouldn’t think that David Was would do the story on Day To Day.
Ayende Rahien’s blog has had the highest signal to noise ratio of any blog which I can think of in recent history. He has posted a series over the past three days on using Castle’s Active Record, including using his own NHibernate.Generics.dll assembly to use .NET 2.0 Generics instead of ISet, IBag, etc with NHibernate. As someone new to NHibernate and ActiveRecord his series of posts arrived at the perfect time.
His posts really sum up to an excellent article. They are of excellent quality. They start with a teaser post that points the reader on where to get some great Castle information. Then he preps you with telling you what he plans to do the next few days. Finally he gets to the first post with all the meat and he does not disappoint. He continues with the aforementioned NHibernate.Generics and Iesi.Collections post. Those posts alone should be enough to get a programmer new to ActiveRecord going. Then he give a where clause example. I’m thinking that along the way he found some room for improvement in his NHibernate.Generics library, because his next blog post is out of the series. He posts an update to his library! I read these in Bloglines and even I noticed that he was making lots of posts. He noticed it himself.
Two more super meaty posts! He even covers lazy loading here! Of course most relational databases have many to many relations and he covers that so finally we programs have all the tools we need to get started.
I recommend you subscribe to his feed, or grab his entire February page and print it. It will be like a fun book. A fun tech book of ActiveRecord with some intermediate SQL sprinkled in for good measure. Between all those Castle Demo App posts he finds time to write about some interesting SQL experiences.
Thanks for the weekend of hard work Ayende. Some of us are watching with great anticipation.
Use Perl on Solaris to talk to Microsoft SQL Server without root privileges
OR
How to install DBI, DBD::Sybase, and FreeTDS on Solaris without root privileges
1. GCC
A. Download a prebuilt compiler
I grabbed the gcc_small-3.4.2-sol8-sparc-local.gz package from sunfreeware. It has a dependancy on libiconv-1.8-sol8-sparc-local.gz, so grab that too.
gunzip gcc_small-3.4.2-sol8-sparc-local.gz
gunzip libiconv-1.8-sol8-sparc-local.gz
B. Extract the packages
You must be root to use pkgadd, but it turns out pkgtrans will extract a pkg for you.
pkgtrans libiconv-1.8-sol8-sparc-local . SMCiconv # here, SMCiconv is the name of the package. If you don't know, just leave it off the command and you will get a menu
pkgtrans gcc_small-3.4.2-sol8-sparc-local
C. Copy files into place
This extracts the packages to directories with the package name. Within those directories are 2 files and a subdirectory. pkginfo and pkgmap contains some package information. The reloc directory contains the files we want.
cp -ri SMCiconv/reloc/* .
cp -ri SMCiconv/reloc/* .
I like to use the -i command so that I know if files in these packages are overwriting each other. I’m copying them to ., the current directory, you can just as easily copy them to some install path, but I don’t mind keeping a bin, doc, etc, info, lib, libexec, share, include, man in my home directory. Remember we aren’t using any special permissions so /var/tmp or $HOME are probably the only places to which we can write files.
D. Configure the package
So now we have ~/bin/gcc… but take a look, it isn’t executable! It turns out this is what information the pkgmap file holds.
grep "^1 f" SMC*/pkgmap | awk '{print "chmod "$5" "$4}' | sh #set file modes from pkgmap.
Another important step done by pkgadd from the pkgmap is creating symbolic links.
grep "^1 s " SMC*/pkgmap | awk '{print $4}' | awk -F= '{print "ln -s "$2" "$1}' | sh
2. Get a development environment
From this point on, I like to have a develop environment defined in my shell. I source a shell script which looks like this.
PREFIX=$HOME
PATH=$PREFIX/bin:/usr/ccs/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/sfw/bin:/usr/local/bin:/usr/local/sbin:/usr/openwin/bin
PERLLIB=$PREFIX/lib/perl
LD_LIBRARY_PATH=$PREFIX/lib
MANPATH=$PREFIX/man:/usr/share/man:/usr/man:/usr/local/man:/usr/sfw/man
PERLLIB=$PREFIX/lib/perl:$PREFIX/lib/perl/sun4-solaris-64int
export PATH
export LD_LIBRARY_PATH
export MANPATH
export PERLLIB
3. Freetds
If you have ever built source packages which use the autotools system, this is straightforward. Just be sure to set your PREFIX.
Download freetds from www.freetds.org.
gunzip -dc freetds-stable.tgz | tar -xf - # Extract the tarball
pushd freetds-0.63 ; ./configure --prefix=$HOME && make && make install ; popd
4. DBI
Download DBI-1.50.tar.gz from dbi.perl.org. It depends on Test-Simple, so get that from CPAN.
gunzip -dc Test-Simple-0.62.tar.gz | tar -xf -
pushd Test-Simple-0.62
perl Makefile.PL PREFIX=$HOME/src INSTALLSITELIB=$HOME/lib/perl && make install
popd
gunzip -dc DBI-1.50.tar.gz | tar -xvf -
pushd DBI-1.50
PREFIX=$HOME/src CC=gcc LD=gcc PERLLIB=$PERLLIB perl Makefile.PL
perl -pi -e "s/ cc$/ gcc/;s/-xO3 -xdepend/-O3/;s/ -KPIC/ -fPIC/;s@INSTALLSITELIB = .*\$@INSTALLSITELIB = $HOME/lib/perl@;s@INSTALLSITEARCH = .*\$@INSTALLSITEARCH = $HOME/lib/perl/sun4-solaris-64bit@;s@PREFIX = .*@PREFIX = $HOME@" Makefile #massage solaris's stupid perl.
make install
popd
Using Sun’s perl to build perl modules can be a challenge, but a few touchups to the Makefile allow us to accomplish what we want.
5. DBD::Sybase
CPAN docs are excellent: http://search.cpan.org/~mewp/DBD-Sybase-1.07/Sybase.pm
Download DBD::Sybase http://www.peppler.org/downloads/DBD-Sybase-1.07.tar.gz
gunzip -dc DBD-Sybase-1.07.tar.gz | tar -xf -
pushd DBD-Sybase-1.07
perl Makefile.PL PREFIX=$HOME/src INSTALLSITELIB=$HOME/lib/perl CC=gcc LD=gcc # press enter at all the prompts.
perl -pi -e "s/ cc$/ gcc/;s/-xO3 -xdepend/-O3/;s/ -KPIC/ -fPIC/;" Makefile #massage solaris's stupid perl.
make install
6. Use it!
Using it involves configuring your etc/freetds.conf file and writing some perl.
The only special part of this is using a sunfreeware package without root access. This opens up many exellent possibilities for using precompiled packages. Getting a compiler opens up even more, and you don’t even have to nag your system administrator. Of course system administrators probably hate developers like me who used to be system administrators.
trivial example usage:
#!/usr/bin/perl -w
use strict;
use DBI;
$ENV{DSQUERY}="myserver"; #this is a [server] defined in freetds.conf
print 'Enter your username: ';
chomp (my $username = <>) ;
print 'Enter your password: ';
`stty -echo`;
my $password = <>;
chomp $password;
`stty echo`;
my $dbh = DBI->connect('dbi:Sybase:database=mydb', $username, $password) or die DBI->errstr;
my $sth = $dbh->prepare('select * from Table');
$sth->execute;
while ( my @row = $sth->fetchrow_array ) {
for my $c (@row) {
if ( ! defined $c ) {
$c="";
}
}
print join(",",@row)."\n";
}
$sth->finish;
$dbh->disconnect;
I’m still an idealist. I still plan on using ogg vorbis instead of mp3. However, the convenience of just using iTunes for listening to music is too great.
474
Four hundred seventy-four ogg vorbis files that I don’t get to play with iTunes. All of which I have ripped myself from my own CDs. All of which I’ve been missing the sound of due to lack of iTunes ogg playback. Today I implemented my interim solution. I’ll put mp3 files right next to the oggs.
http://marginalhacks.com/bin/ogg2mp3 has a nifty perl script, which could just as easily be shell, but in a linux world, we always have perl 🙂
This script uses ogg123 to extract a wav file from the ogg, then uses lame to encode that wav file. Coupled with my shell prowess, I can put mp3s right next to all my oggs.
What shell prowess? I like this oneliner.
find . -name '*.ogg' | while read i ; do if [[ ! -e "${i%%.ogg}.mp3" ]] ; then echo doing $i ; ~/src/ogg2mp3 "$i" ; fi ; done
Not a oneliner you say? Well I typed and constructed it on one line.
Maybe this is easy to read?
find . -name '*.ogg' |
while read i
do
if [[ ! -e "${i%%.ogg}.mp3" ]]
then
echo doing $i
~/src/ogg2mp3 "$i"
fi
done
I love bash.
If you aren’t a master of the shell, then you may want to know just what is going on here.
I used find and piped to while read. why?
I could have used for i in `find`, but for splits on spaces, and many of my files have spaces in the name, so I used while read to capture the entire line output of find, which in this case is the filename.
I could have used find . -exec “ogg2mp3”, but then I don’t have access to shell builtins which I used to do my if statement.
My if statement checks to see if the ogg file is already there. The %% is a TrimRight function. It trims the .ogg off the end of whatever is in the i variable. Then I add the mp3. So if the mp3 doesn’t exist, then we create it. This makes it easy to stop can continue the process as well. Files that are already there will not be converted again. Of course if lame writes incrementally as it is doing the conversion, you could break in the middle of a conversion and have only part of an mp3. Don’t do that.
About the shell builtins, I used to sysadmin unix on some old slow computers. Creation of new processes was expensive. I’ve never given up always thinking about process creation and costs. ogg2mp3 wouldn’t take multiple files to convert on the command line, or else I would have used my beloved find -print0 | xargs -0 pattern. If I had used -exec and started bash instead of it, maybe something like find . -name '*.ogg' -exec 'bash -c \'if [[ ! -e ${\{\}%%.ogg}.mp3 ]]; then ...fi\''
. It would have started a bash process for every cycle of the loop. Sure it is only 400+ in this case, but I’m used to scaling to 10,000, 30,000, or 100,000 … to I don’t care how big. Not to mention I find the escaping of the quotes and the curly bracets to be less readable this way. In fact, I think I have curly bracets escaped incorrectly in that -exec block. oh well.
After a day at work in Windows world, it is nice to return to the power and simplicity of the bash shell and gnu tools.
A very good friend of my is a web designer who has always struggled with programming. He found the Absolute Beginners – PHP 101 series of articles from Zend to be extremely helpful. I noticed he is learning things better this time simply by the types of questions he asks me. He started asking me some database things and my immediate response was “don’t do it that way”. My response was of course wrong. After all, he was just learning. The 8th article in the series introduces database access and honestly it feels a bit out of place after the first 7 articles. The first 7 take an almost programming 101 (php101 right?) approach and give good fundamentals. With a little bit more background in each article, the series could almost be the first few weeks of an introductory college level computer science (programming) course. The next steps would be to introduce data abstraction, common abstract data types, and algorithms, but Zend knows their audience here. These are people who just want to get things done.
http://www.zend.com/php/beginners/php101-8.php is the article to which I am refering. It is fine and there is nothing wrong with it, but it does lead the new programmer down a dangerous path. There is no mention of abstraction.
Using an abstract library instead of direct database function calls means that if you want to switch databases from MySQL to PostgreSQL in the future, it will be a lot easier. Here is what the example code might look like.
Instead of calling the mysql_ suite of functions directly, PHP provides an excellent Database Abstraction library in the PEAR library known as PEAR::DB. I used PEAR::DB back in 2001 on one medium sized web project and it worked great. I had used it prior for many months without issue. I’m sure it has matured over the past 5 years.
I had initially written an article directly converting the examples in the Absolute Beginners – PHP 101 article 8 to using the PEAR libraries. Due to a horrible typo, I lost an hour of work and I never revisited this task. Instead of write a side by side comparison of direct mysql_ function calls to PEAR::DB connection instance OO calls, I’ll simply reference a PEAR:DB tutorial article. A great article is available at evolt called Abstract PHP’s database code with PEAR::DB. A huge list of resource is available from PHP Kitchen. International PHP magazine has an Introduction to PEAR which eases the reader into PEAR::DB.
So before calling a mysql_, pg_, ibase_, fbsql_, db2_, maxdb_, mssql_, sqlite_ or some other database function, consider using PEAR::DB, so that you don’t have to guess if s/mysql_/pg_/ will work or not. Of course, writing cross database SQL is something else entirely, but this is a necessary first step.
From Mark Ramm’s in person class. Only 11 people, including myself, so I didn’t feel like I was squatting. Well, at least not too much.
My knowledge from Python 1.4 days is pretty much useless.
Mostly in comparison to other languages.
Lists in perl vs. python:
Python Perl
l.expand(element) push @l, $element
l.pop() pop @l
l.insert(0,element) unshift @l, $element
l.pop(0) shift @l
help() is every bit as capable as perldoc
List comprehensions are just a big name for some iterator syntax sugar. (sorry python guys, that is my take).
Introspection in python is WAY easier than Reflection in .NET.
help(modules), help(), import __builtin__;help(__builtin__), are great starting points for help in python.
True, False, and Null have some interesting properties. 0, [], (), “” (zero, empty list, empty tuble, empty string) are all considered false. Yet comparison with True or False still yeilds false. I think the logic is similar to NULL in SQL, but I have not found definitive Python docs stating such.
Python uses different terms to describe things. Member variables are called attributes. C, C++ and C# have attributes but they are entirely different things.
There are no member access modifiers in python (no private, public, protected and internal).
This TurboGears course is definitely beyond me. The fact that I’m having trouble installing it on my laptop is a bummer. I’m thinking setuptools and windows don’t like each other that much. TurboGears subversion may work better, I don’t know. (5 min later… I do know. I hate that IBM ships python and it is in my default path on this T42… Major Oops!)
TurboBlog is a turbogears open source blog software which may be good to examine when learning turbogears.
Here is my 2 line wordpress cache.
wp-includes/classes.php~ 2006-01-24 22:59:41.000000000 -0500
+++ wp-includes/classes.php 2006-02-03 10:39:57.370444690 -0500
@@ -1612,7 +1612,8 @@
status_header( 404 );
} else if ( empty($this->query_vars[’feed’]) ) {
@header(’Content-type: ‘ . get_option(’html_type’) . ‘; charset=’ . get_option(’blog_charset’));
– } else {
+ } //else {
+ {
// We’re showing a feed, so WP is indeed the only thing that last changed
if ( $this->query_vars[’withcomments’] )
$wp_last_modified = mysql2date(’D, d M Y H:i:s’, get_lastcommentmodified(’GMT’), 0).’ GMT’;
I have no idea why wordpress doesn’t return Last-Modified headers by default, but this little patch at least gets it to return something! This will help cache servers, and spiders. They won’t read a file that they already have.
Stolen from Bill Wagner
<quote>
A short commercial announcement
I’m posting this to announce the inaugural meeting of the Ann Arbor .NET Developers Group. In a short time, you’ll be able to read all about our group at www.aadnd.org. (It’s not live yet). Our mission is to educate software developers in the greater Ann Arbor MI area about .NET development practices with the goal of helping our community of developers grow professionally.
2/8/2006 – First Meeting
6:00 to 6:45 – An Introduction to ASP.NET 2.0
Speaker: Jay Wren
< interupt quote >
ASP.NET 2.0 is a powerful and compelling web application platform. Many of the patterns of traditional web development are completely abstracted using OO concepts, ASP.NET Control, and other .NET concepts. How did we get here? How do we get started using these tools and thinking at this new level? A gentle introduction to ASP.NET 2.0 demonstrates some of what can be achieved using this web application platform.
< /interupt quote >
7:00 to 8:30 – It’s all about you! Personalized Web Sites with the ASP.NET 2.0 Portal Framework
Speaker: Josh Holmes
Your users can go to thousands of web sites. Why do they come to yours? It’s for content that they are interested in. The more focused this content is on them, the more likely they are to re-visit. Through the ASP.NET 2.0 Portal Framework, you can allow the user to narrow that focus and refine it to just the content that they want to see. http://my.msn.com has been using this framework for some time now but it’s available to us now so you will see a lot more personal portal sites popping up. Rather than building web sites, the portal web site developer will focus on building panels of content, called web parts, similar to SharePoint web parts. In this talk, we will discuss how the framework operates as we build a simple web portal application completely with web parts.
We will also be supplying pizza and pop between our tutorial and our main presentation.
Our ongoing meetings will be on the 2nd Wednesday of each month, from 6:00 pm until 8:30 pm at Ann Arbor Spark Central. (330 E. Liberty, Lower Level).
We’d like to see you, and as many other .NET developers you know join us.
</quote>