From Node to Ruby on Rails | D U N K

Building the web app in Rails took me 2 days – the same thing in Node would have taken 2 weeks. I’ve also included things I wouldn’t have attempted to build on Node/Express until I proved the idea out (editing a profile? Psht please – I’ll wait till someone requests that). People in the HN comments always accuse the Node ecosystem of making you re-invent the wheel for every project. But I thought that was just the way things were. Now I realize the truth to their words.

Source: From Node to Ruby on Rails | D U N K

I’ve been saying this for years, but DHH endorsed this writeup.

SQL Is Obnoxious

I find SQL obnoxious, due to its brevity. Getting complicated desired behavior from it sometimes requires clever understanding and combinations of very simple primitives. Because it’s taken me about 2 weeks (off and on) to work it out, I present, with no explanation, this code:

WITH vars (var) AS (
  SELECT UNNEST(string_to_array(ancestry, '/')::integer[]) FROM calibrations AS a
)
SELECT c.id AS cal_id, p.id AS param_id, t.id AS tuning_id, o.* FROM tunings t
  LEFT JOIN LATERAL json_array_elements(t.data::json) WITH ORDINALITY AS o ON TRUE
  JOIN variables v ON v.tuning_id = t.id
  JOIN calibrations c ON v.calibration_id = c.id
  JOIN parameters p ON p.label = t.label
WHERE c.id NOT IN (SELECT var FROM vars)
  AND t.data_type = 'Z_Axis'
  AND p.label = 'C_PME_GainFactor_Table'

OKAY | Why the status quo is so hard to change in engineering teams

Before we talk about how to prevent it, let’s see how learned helplessness can happen in a development team. There are 2 main patterns:

Pattern #1: Process-related Learned Helplessness

In this case, the team needs to follow processes that have either been externally imposed, or internally imposed but no-one remembers exactly why.

Pattern #2: Complexity-related Learned Helplessness

In this other case, the source of powerlessness is sheer scale and/or complexity. There is truly no-one who understands the emergent behavior of the system.

Source: OKAY | Why the status quo is so hard to change in engineering teams

So I’m currently reading the book Learned Optimism, by Martin Seligman, which just so happens to be the seminal psychological work which teaches people how to combat learned helplessness. I’ll skip trying to give a primer on the process, but the one key that I need to talk about here is that you have to be objective in finding explanations for negative things in your life. Pessimists generally blame themselves for everything, and we all know that’s not fair. Even pessimists wouldn’t blame other people for their own problems when it’s obvious that they aren’t, but they will happily continue to blame themselves for problems that they know they are not responsible for.

People often think I’m a pessimist, but I’m not. I’m objective. I’m so objective that it’s almost a superpower. In that objectivity, I often realize that I am the source of the problem. That may appear to others that I’m a pessimist. However, I’m not afraid of calling a spade a spade, and pointing out that a problem is someone else’s fault, either. And I’m about to explain how this whole topic of discussion is, in fact, someone else’s fault, it’s systemic, and it’s not going to change.

The quoted article found its way to “Hacker” “News,” but you have to understand that this is a blog post from a company which sells software that purports to solve these problems for teams of programmers. I say, “hogwash.”

Every one of the problems listed in the article is the result of bad management.

Period. There’s no getting around it, and there’s no sugar coating it. In the vein of the article, “there are 2 main patterns” why.

First, in our modern feudalism of corporations, the low-level managers are like barons, the middle managers are like earls, upper managers are like dukes, and the C-levels are like princes. Everything flows from the top down. Everyone is playing political intrigue for more power, in the only terms that the corporate structure can understand and deal with: budget and headcount. No one will deal with fixing a problem if it doesn’t directly contribute to their standing with their peers or superiors, and problems with software build systems, infrastructure, or technical debt are simply invisible to anyone not dealing with it directly.

Second, the days of building a company to last 100+ years is gone. J. Irwin Miller built Cummins into a world-spanning empire, and then retired. Then the company started implementing all the trendy business-school ideas, and was getting run into the ground. Miller came out of retirement and righted the ship, and then retired again. Those days of people caring about a company like this are gone. Everyone is out to “get theirs,” and then hit the brcks. Everyone knows this, but we still like to pretend that anyone in the bridge cares if the company actually survives in its efforts to make the next $100M.

From HR systems to compensation to benefits, companies are deeply, deeply afflicted with myopic vision. It’s driven from the very top, where every decision of significance is made in view of the almighty stock price. Corporate boards encourage this behavior by tying executive pay to stock options. For decades now, we’ve watched big companies sacrifice long-term performance for short-term gains, because it will net the corporate officers tens of millions of dollars in stock grants. If there’s any hope in this situation, it’s that most of the excess capacity in corporate America has already been wrung out (q.v., the recent supply chain issues), and there’s nothing left to pillage, either internally, or by corporate raiding. (The play now is to merge to form effective monopolies and duopolies, and extract all the profit from your market, but that’s another topic.)

When you combine a lack of visibility with a lack of vision, you get an appalling lack of concern for issues that the rank-and-file serfs deal with.

The fact that issues that programming teams deal with are highly-technical doesn’t matter at all. In fact, it works against them, because fixes are more expensive than in other teams. Say, like buying yet another web service, on top of all the others you already subscribe to, in order to apply metrics to problems that management will never fix, because they neither understand nor care.

There are a lot of examples I could write about here, but one stands out. I know of a person who was briefly involved with an effort to quantify the development process for his Fortune 150-sized company, much like the linked article. When he talked with a knowledgable insider about the system, it was one shocking revelation after another. The system was down more often than it was up. There was no way to estimate how long a build would take. There was no way to check on the current load of the system. There was no way to check on jobs, other than to log into a remote machine and tail a log file. The system wouldn’t even send out an email at the end of the build to indicate success or failure, because it would show how badly the whole thing performed.

So a “baron” in another group got the bright idea that they would oversee the writing of a dashboard to overlay metrics on the process, so that the “earl” who was responsible for it could “see what parts to focus on.” Let that sink in… Do you see the problem here? This manager thought that he would be allowed access to the various running processes of the system, to quantify, graph, and display them — like, on the shared screens in common spaces — when the owner of the system wouldn’t even allow emails about the success or failures of builds to be sent out, which is the most basic of all metrics, and which would have required only a single checkbox to be ticked. The mere idea of this project was so hopeless as to border on insanity.

The people responsible for the system already knew about its problems. They didn’t need metrics. They didn’t care! Whether that was from a lack of budget or a lack of headcount or a lack of technical ability or a lack of communication with other teams… none of that mattered. The people responsible for the system weren’t willing to spend their political capital to fix the problems of the system. And whether that lack of will came from their own political ambitions or a lack of understanding or a lack of vision… none of that mattered either.

The article talks about why developers get frustrated, and proposes that metrics will fix it. Their system won’t help, because, in most companies, it’s not about a lack of metrics. It’s a lack of will, motivated by personal ambition, gamed by incentivizing short-term productivity. As a developer in a group like this, you can blame yourself, or you can look for opportunities internally, or you can take your show to a different stage. All of those responses are in the HN thread about the article. We all have to find our own balance points between our predilections and our companies’.

As a developer, you can alter your internal “explanatory style” to move the blame for the problems you have to deal with to systems or software or people, but all of that misses the real point.

In post-modern, Fortune-sized, American corporations, the problem is management, and all management starts from the top. The corporate officers set the leadership paradigm the rest of the company will adopt, and they are being strongly incentivized against long-term investment in tooling and process. This mindset trickles all the way down to the bottom. If there are problems with “getting stuff out the door,” they will almost always hire more people, because that’s almost always the easier and cheaper solution than retooling an entire department with new software and process. And then, every 5-10 years or so, they will bury their failure to address actual productivity problems with yet another “reorg” or sweeping IT platform change.

Ruby on rails : problem of verifiying the SSL certificate while installing bundle

I’m new with ruby on rails and while creating my first project with this command rails new n_project, i got this error

run bundle installFetching source index from https://rubygems.org/ Retrying fetcher due to error (2/4): Bundler::Fetcher::CertificateFailureError Could not verify the SSL certificate for https://rubygems.org/.
There is a chance you are experiencing a man-in-the-middle attack, but most likely your system doesn't have the CA certificates needed for verification. For information about OpenSSL certificates, see .... To connect without using SSL, edit your Gemfile sources and change 'https' to 'http'.
Retrying fetcher due to error (3/4): Bundler::Fetcher::CertificateFailureError Could not verify the SSL certificate for https://rubygems.org/.
There is a chance you are experiencing a man-in-the-middle attack, but most likely your system doesn't have the CA certificates needed for verification. For information about OpenSSL certificates, see .... To connect without using SSL, edit your Gemfile sources and change 'https' to 'http'.
Retrying fetcher due to error (4/4): Bundler::Fetcher::CertificateFailureError Could not verify the SSL certificate for https://rubygems.org/.
There is a chance you are experiencing a man-in-the-middle attack, but most likely your system doesn't have the CA certificates needed for verification. For information about OpenSSL certificates, see .... To connect without using SSL, edit your Gemfile sources and change 'https' to 'http'.Could not verify the SSL certificate for https://rubygems.org/.
There is a chance you are experiencing a man-in-the-middle attack, but most
likely your system doesn't have the CA certificates needed for verification. For
information about OpenSSL certificates, see ...

Source: Ruby on rails : problem of verifiying the SSL certificate while installing bundle

I develop software using a pretty varied mix of technologies, including C#, VB, Postgres, SQL Server, and Azure services of all kinds, but mostly Ruby on Rails. After 15 years of using it, I find that it remains one of the most force-multiplying tech stacks in the world. With it, by myself, I can develop software faster than entire teams of outsourced, waterfall-managed, Java/React projects. (And I proven that multiple times.) Not only that, but the future is looking even brighter with Rails 7.

Anyway, I develop software on my personal MacBook Pro, upload it to a git host, and deploy it to a Linux VM on Azure. But my work-supplied laptop is, of course, a bog-standard, boring Dell running Windows. I feel an obligation to be able to use it to do everything I would normally do on my Mac, just in case the hammer falls, and they outlaw the way I work. So, on Windows, I use RubyInstaller. But, thanks to my company’s bog-standard industry practices of using Cisco products to lock down the laptop within an inch of usability, I’ve been unable to do a bundle update for awhile now, getting the error listed above.

I had previously worked around this situation by using CNTLM to tunnel command-line-based HTTP/S requests through my company’s firewall. This was no longer working.

I tried changing my Gemfile to use HTTP, instead of HTTPS. I tried getting gem to ignore SSL errors (and use HTTP sources). None of this worked either.

Yesterday, I had finally had enough of the problem, and decided to work through it. Helpfully, the error message included the fact that I was missing the Cisco Umbrella CA certificate in the certificate chain. Also helpfully, Cisco has a page where you can download their certificates, ciscoumbrellaroot.pem and crca2048.pem. Also helpfully, I found the linked StackOverflow Q/A. That got me started, and I finally figured out the RubyInstaller people have anticipated this problem. There’s a proper way of adding a certificate to your chain. Just drop the certs in C:\Ruby-xx-x64\ssl\certs. This allowed me to get rid of all the hacky workarounds, and now bundler works like I expect it to work on my work laptop.

Arch Linux

I finally took a look at Arch Linux. I started the process of installing it with Parallels on my MBP. I got to the GRUB configuration step, and then thought, “What in the world am I doing!?” And then I quickly deleted the VM and the install ISO. In the immortal words of Sgt. Murtaugh, “I’m getting too old for this.”

Kinda a big announcement – Joel on Software

I took a few stupid years trying to be the CEO of a growing company during which I didn’t have time to code, and when I came back to web programming, after a break of about 10 years, I found Node, React, and other goodies, which are, don’t get me wrong, amazing? Really really great? But I also found that it took approximately the same amount of work to make a CRUD web app as it always has, and that there were some things (like handing a file upload, or centering) that were, shockingly, still just as randomly difficult as they were in VBScript twenty years ago.

Source: Kinda a big announcement – Joel on Software

It’s hard for me to express just how deeply wrong I find this to be, but I suppose that’s because I take it as an almost personal insult. Here’s a smart, driven guy who probably just became a (near) billionaire with the sale of a site devoted to programming Q&A, and yet, in my opinion, he’s completely out of touch with modern web development. I really resent this gaping hole in the collective knowledge of programmers on this planet.

I’ve been using Rails for 15 years now. I’ve used it to make dozens of applications. It is perfectly suited for making CRUD web apps. It was designed from the ground up to do so, and avoid the grunt work of other programming stacks, specifically Java. Unfortunately, Spolsky is not alone of his ignorance about it. I see lots of programmers singing the praises of Javascript, who dismiss Rails, usually because of its convention-over-configuration approach, but nothing can compare to the productivity of using Rails to write a CRUD web application. Nothing. It’s not even close. He’s absolutely right that Node and React offer no advantage over any other legacy option like Java or .NET. I went down the whole Java/Spring/Angular hole for one ill-fated project, and it’s a freakish, byzantine nightmare. The difference between the two stacks is so stark that I have to assume that people who make these kind of comments are completely oblivious to the fact that Rails exists at all.

Take file uploads for instance. Rails has had easily-configured and power capability from several hugely popular gems since (at least) the 3.x days. The stack has had its own implementation since 5.x. Either way, just configure a couple of lines in an initializer, pick a provider, enter your bucket name and API key, and then it’s literally just a few lines of code to add a file attachment to your model.

Spolsky continues to rant:

The biggest problem is that developers of programming tools love to add things and hate to take things away. So things get harder and harder and more and more complex because there are more and more ways to do the same thing, each has pros and cons, and you are likely to spend as much time just figuring out which “rich text editor” to use as you are to implement it.

This is the continuing, enduring beauty of Rails. They continue to add things to the stack, like file uploads, but they do so in a way that makes them optional. If you want them, it’s, like, 3 lines of configuration, and you’re rolling. A rich text editor, as it turns out, is another perfect example. There has been a popular gem to provide the WordPress editor for a long time now, but Rails started shipping a native rich text editor in 6.x, if you want it. I’m using it in a significant way in a production application right now. I added it well after the site was launched, but it was easy, and it’s terrific.

Today we’re pleased to announce that Stack Overflow is joining Prosus. Prosus is an investment and holding company, which means that the most important part of this announcement is that Stack Overflow will continue to operate independently, with the exact same team in place that has been operating it, according to the exact same plan and the exact same business practices. Don’t expect to see major changes or awkward “synergies”. The business of Stack Overflow will continue to focus on Reach and Relevance, and Stack Overflow for Teams. The entire company is staying in place: we just have different owners now.

This is where I get worried. An investment and holding company paying $1.8B to buy a site like Stack Overflow is going to want to recoup its investment, and make more money in the future. In the old days, they used to say that investments needed to start making money in 7 years. I’m not clear that this old rule of thumb still applies, and SO is a private company, so we can’t see a balance sheet, but does anyone think that “SO for Teams” is making $250M a year? Big M&A announcements like this always say the same things about keeping the product the same. Let’s revisit this in a year, and see where we really stand.

Nine things we learned from the Epic v. Apple trial – The Verge

It’s particularly notable since some people are worried that macOS is inching toward the iOS model, making it a little more difficult to install unauthorized software with each new version. If you were already anxious about the Mac ecosystem closing off entirely, Federighi’s testimony gave you plenty more to worry about.

Source: Nine things we learned from the Epic v. Apple trial – The Verge

Indeed. Federighi says he’s worried about malware on macOS. I think that’s scaremongering. (Now watch me get a virus.) But, for all-around safety, I’ve come to the tenuous conclusion that requiring everything to be signed is acceptable. However, if Apple finally closes the last door, and begins to require that everything you install on a Mac to come through the App Store, we’re going to have a problem. As a Rails developer, I’m very worried about the trend of making macOS more and more like iOS, but I don’t seriously think they can ever do this, completely, and I’ll step through why.

A large part of the reason that Apple sells Macs is for development. Obviously, developers must make up a very small percentage of Mac users, being dwarfed by media creators, but the inescapable reality is that Apple themselves require a Mac to write software for their most-profitable products: the iPhone and iPad. So, even by Apple’s own rules, a generally-open development environment needs to exist to continue to support their mobile ecosystem.

Very closely related to this is that a lot of developers (like me) prefer the platform for developing web apps, which, again, is a type of development that helps Apple’s efforts. I mean, they don’t want people going off and creating Windows-native applications, right? So keeping the operating system of Macs in such a state as to make it productive for web development is — at least tangentially — also in their own best interests. However, this sort of focus almost requires the use of either Homebrew or MacPorts, which I have a hard time believing could be delivered through the App Store.

So, following the logic, and while I understand that it might be really attractive to Apple leadership to lock down macOS as tightly as iOS, I don’t see a path for getting there. At least, not in a way that won’t alienate the entire demographic of developers. Obviously, if they get really serious about it, they could lock the system down for iOS app development, but I think this would leave web development blowing in the breeze. If that were to happen, my only consolation is that Linux is just as nice for doing Rails development as macOS. It’s not as great for just about everything else, but it is a first-class platform to develop web applications on. So, moving back to Linux on the desktop is a viable fallback position for me, and the really great thing about that is that no one can take that away from me.

Time Tracking Web Apps

I work for a tech outsourcing firm, but I’m fully-subcontracted to a Fortune 250. My company recently switched away from their home-brew time tracking tool (which wasn’t completely terrible) to Workday. The transition was rough. You had to click several times to finish the process, and it was easy to miss. They’ve since changed the workflow, and it’s better, but the site is still laggy. Apparently, Workday is taking over the world, and this makes me sad. It’s not a great system.

The Fortune 250 recently wrote their own time tracking tool, and now I have to enter my time in this second system as well. It’s everything I’ve come to expect from an internal application written by #CorporateIT. It’s slow. Like, really slow. Every time you type a number, it does something in the background, so filling in project numbers takes several seconds. Entering a number for time takes just longer than you expect, so it’s constantly tripping you up. Did it take the number? Oh, wait, it did, and now I have 88 hours in the box. Today, it broke the tab key. So, you know that thing where you would hit 8 and then tab, five times in a row, and be done? Not happening. This is something that you get for free in a browser, which people rely on, due to muscle memory, and the way every other table-based UI works, like Excel. You have to purposely disable this behavior. This strikes me as bizarre, but I guess it doesn’t really surprise me.

I wrote attendance-taking software for my church, which we used for a dozen years. It had features we still miss now that we use one of the main church management software sites. And it was fast. Like, millisecond fast.

I wrote my own home-brew time tracking software for a previous company. The first version sucked. It was slow, too. But, after getting it “in the neck” about how bad it was, at one all-hands meeting, I took the initiative, spent a week re-designing the core of it, and made it fast. Really fast. I profiled it at literally 20 times faster. The owners were happy. And then I wrote a page to do two pivot tables for the time period, one by employee (to write paychecks) and one by customer (to write invoices), and the person who did both of those things was happy too. This saved her many hours every week. That was 11 years or so ago, and the last time I asked, they were still using it.

These systems aren’t really that complicated. This is a well-known problem space, which every company needs addressed. Why are they all so terrible? I think it all comes back to the basics. The people who have to deal with it are not the people designing it, or specifying it. Once a company is so big that this disconnect can happen, I don’t know how it ever gets fixed. I fixed my app because the owner said it sucked, and I fixed it. In a Fortune 250, no one who has the authority to say that the time-tracking app sucks will ever have to use it, or even speak to someone who has to.

TECH | Stop using JPA/Hibernate · Blog de Laurent Stemmer

Here an example of a JPA entity (using Lombok for “simplicity”): <sarcasm quotes mine>

@Entity
@Table("offer")
@EqualsAndHashcode
@NoArgsConstructor // for Hibernate
@Setter // for Hibernate
@Getter
public class BankAccount {
    @Id
    @Column("id")
    private String id;
    @Column("opened")
    private boolean opened;
    @OneToMany(fetch = LAZY) // ...simplified
    private Set ownerIds;
}

Source: TECH | Stop using JPA/Hibernate · Blog de Laurent Stemmer

Through a very long series of unfortunate circumstances, I was backed into using Java/Spring/Hibernate/Angular in a doomed project. This page had me nodding my head in agreement, and this code reminded me of the Lombock portion, which was its own special nightmare. I just went looking for what I had written for that project, and it would appear that I’ve totally deleted it. I normally keep everything, so I can go back and refresh my mind when I recall some particular technique I’ve used in the past, so this should tell you something about the brain damage using this stack will incur.

I’m going to digress to setup a point. I used gvim for many years, with a complicated setup, using NerdTree and several other plugins, to give me a UI with my project’s directory on the left side, and tabs of open files on the right. At some point, I got tired of fiddling with the configuration, and finally started using someone’s massive-but-well-integrated ~/.vim configuration from a GitHub repo. Finally, I realized that I was spending all this time and effort on making gvim work just like Sublime Text did out of the box, and I could just start with that. So I did. While I’ve flirted with other editors (notably, Visual Studio Code, and the excellent IntelliJ, while working on Java), I’ve basically stuck with it for about 7 years now.

Here’s the parallel. The thing that fans of the Java ecosystem can’t admit to themselves is that this whole stack: Java, Spring, Hibernate, Lombock, Javascript, AngularJS, etc., et. al., ad naseum… is all just a terrible pile of Jenga blocks which putatively exist to give you a functional environment like… wait for it… Ruby on Rails! Lock, stock, and out of the box. It seems to me that the motivation of people who still like to use gvim when Sublime Text and Visual Studio Code exist is the same sort of motivation of people who like to use a Java stack over something like Rails. Maybe they’ve done it so long, they can bang out the boilerplate with their eyes closed. Maybe they like the way you have to do everything explicitly. Maybe it makes them feel like a hacker.

All of the code above reduces to this in Rails:

class BankAccount < ApplicationRecord
    self.table_name = 'offer'
    belongs_to :owner
end

In an absolutely brilliant display of one of the biggest problems with using this Java stack, I went to remind myself what the @Table("offer") directive does. I am pretty sure it specifies the actual SQL database table name storing the instances of this object, but I literally can’t find any references to this pattern in the Lombok documentation. It is only through inferring it from a StackOverflow question that I am reasonably confident that this is, in fact, what it is doing. And if it weren’t for Spring and Hibernate and Lombok, there’d be about a hundred more lines of boilerplate code in that single class file.

The top comment thread on the HN discussion about this blog post points out just how bad of an ORM Hibernate actually is. With 15 years of experience with Rails under my belt, I can assure you that almost none of those issues apply to ActiveRecord. Of course, I’ve seen people complain about AR, but I think their arguments are always exaggerated, and probably come from a place of general discontent with having to use Rails at all. People like to complain that Ruby is “slow” because it is interpreted, but it’s precisely that on-the-fly reflection/interpretation that allows ActiveRecord to be so good at being an easily-programmed and powerful ORM. It’s trading machine time for ease of development and readability, and I have yet to see a situation where that was a bad tradeoff. When I encounter speed problems with using Ruby, I do something else. Either I optimize the loops, or push more processing to the database, or write the heavy-duty computation in something else entirely, like R.

While I’m on the subject of ORM’s, I find EntityFramework just as bad as Hibernate. I suppose it’s just the nature of an ORM in the context of a compiled language. After giving it a real college try, I gave up on it. I wrote a serious application in Visual Basic and C# which accessed the database through a library of functions wrapping raw SQL, and called them from the WinForms side, and it worked out very well. I’m glad I didn’t try to force EF to work.

So, sure, rag on Rails. Call it slow. And, yes, compiled Java will always be “faster” than interpreted Ruby, but all the Java web sites I have to interact with are noticeably laggy and sluggish, compared to my apps, so there’s something to be said about the actual implementation, over the theoretical concept. While whole teams of “Java” devs are still writing class files in Java (and Javascript), for their object models, I’m done with my app, and moving on to the next one.

So, yes, by all means, please stop using JPA/Hibernate, but, I would go one step further, and advise people to just stop using Java for web apps entirely. That horse got passed 15 years ago. Even if you don’t like Rails, there are at least a few other stacks that would be far more productive than Java for web apps these days. Heck, I’d try to do Javascript on the frontend and backend before I’d try doing Java again. <shiver>

And that’s my “2 minutes of hate” for today.

Build Your Own Database Driven Website

I don’t remember what prompted me to remember this book, but it was, perhaps, the biggest influence which has shaped my career. I had already been a programmer since I was a kid, and I had already written a couple of well-received programs on my job by the time I bought it, but I had actively avoided learning about databases, in order to focus on other Windows and Visual Basic, and I hadn’t gotten long-enough arms to break into web programming until then. Thank goodness, too, as it was all cgi-bin Perl stuff leading up to PHP. Yuck!

Reading books on programming is never fun for me. I’ve tried to read a couple on Ruby and Rails, and I just can’t get through them. The problem is that the ratio of stuff I already know to the stuff I don’t is so high, I can’t slog through it. I get too bored while trying to get to something new to me, and put it down. This book, however, hit me right between the eyes. It was the perfect book for me at the time. It was very thin, and there was zero fluff. I rewrote my FrontPage blog site in PHP in a week with the help of this book, and I was off and running. I’ve been doing primarily web app programming ever since.

Anyway, I just am fond of the memory of this book, Kevin Yank, who wrote it, and SitePoint, which was started around these books. This version is old and out of print, of course, and he seems to have retired now. If so, good for him. Thanks, Kevin.