That's a neat tool you mention... is it available on Linux or OSX???? :P
HN user
darrencauthon
I'm waiting to see the alternative.
It's an honest question to ask in the face of an assertion about testing -- or how strong or static typing eliminates the need to verify that the code behaves as written. In the sample I provided, I provided a concrete example as to how I could verify that the code accomplishes the task. If tests are not needed, then fine... show me how with code that accomplishes the task and that show how.
Like the "unit" where the two operations are covered in one method... Sure, but how else would it be done? The client asked for the log and the email, so somehow, someway... someone has to write code to do it.
I threw up my Ruby sample in just a few minutes... why can't the alternative be coded up in a few more?
Yes, my gist, but also a Twitter conversation on how strong typing altered the need for tests. I've heard from a couple Haskell programmers about how the language practically eliminated the need for tests. I don't see how that's possible, but I also know Haskell.
I asked for a specific code example, and I threw out the scenario of a client who wants a contact us form that logs all responses and sends notification emails. I threw out a simple Ruby example where I tested the functionality, and I'm waiting to see the alternative.
You know, I've heard of Dash and my knee-jerk reaction has always been, "Eh, I'm ok lookin' stuff up."
But you know... maybe I'm not. I just installed it, and I'm going to give it a try.
I couldn't finish it all - yet. It looks like this took a while, thanks for the attention!
Does anyone know of a public example of a Rails application that does testing in the way that DHH says is good?
I'm tired of the talk talk talk talk talk talk of "proper" testing in Rails, yet the examples always seem to be hidden away behind company firewalls. I've only seen a couple Rails apps with Rails-Way test suites, and they were nightmares that took many minutes to run. But I have seen dozens of Rails apps written by opinionated Rails devs with strong views about what proper testing was... and the apps had no tests at all.
This article is hilarious. If you want to see why TDD, unit testing, isolation, etc. are important, a Rails app written the "Rails Way" is the first place you should look.
They all look the same. They start out with great tests, verifying that the simplest CRUD operations are covered. Then as the changes come, the tests fade away. Their big browser-driven tests are so slow, brittle, and difficult, the question of "should we test this?" becomes paramount as they try to convince themselves that their code doesn't need tests. And even the most ardent TDD proponents and green-band wearers are suffocated as they have to admit that, yes, for the business' sake we cannot spend days building a test harness to test if a new field is required.
I hope this article is the myth-buster to the fantasy world that the Rails community takes testing seriously.
This mistake shouldn't happen?
Mistakes always happen. Even if I dedicated myself to using braces everywhere, my mistake might be that a) I put the braces in the wrong place, or b) I forgot to put the braces.
His code example is:
if (error_of_fifth_kind)
goto fail;
goto fail;
if (error_of_sixth_kind) goto fail;
The_truly_important_code_handling_non_erroneous_caseMy question: If the "truly important code" is really that important, where are the unit tests to verify that it "handles" the "non erroneous case????"
Test. Your. Code.
I don't think your model has to have 1200 lines of code to see the benefits. DHH's ticket class stars with 2 lines of model code, which is a very rare case in the Rails applications I've seen. Counting by hand, I see DHH's example has one, two, three...
Twenty-six (26) lines of model code that are dedicated to validating this specific "confirmation" validation.
Given that validation is just one of the concerns of models built with The Rails Way, imagine sprinkling all of the other code that a model will have in-and-around these 26 lines of code. The central purpose of those 26 lines of code vanish into the fog of the rest of the model, creating the mystical behaviors that are common in some Rails applications.
I totally understand the concern about preemptive architecture, but once the code count for a given behavior creeps from 4, to 8, to 12... it's time to organize it into some sort of central place that's isolated from the rest. I mean, gosh, we know how this works in the real world, right?
Dev A: Here's my 26 lines of validation code to the model, DHH says it's the right thing to do.
Dev B (hours later): I need to add a little bit of behavior here, but I'm only adding a little bit of code. I'm not going to try to deduce what all of that code does, so I'll just tack mine on the bottom.
Dev C (days later): I have to add a bit of code... hmm... this is sort of a mess, I see mostly validation code but I also see some behavior. I'm not touching any of it. I'll just patch my stuff here... and here!
[iterate over and over, you get a mess of a Rails app]
I've seen this happen to multiple Rails applications... Rails applications built by experienced developers who know Rails in-and-out.
Plopping a bunch of code in something as important as a Rails model and leaving the cleanup for the next dev isn't very polite.
I'm a fan of Ayn Rand and her books. But pointing out obvious issues with this article doesn't take a fan, it just takes someone who knows her work. It's not correct.
"Ayn Rand’s novel “Atlas Shrugged” fantasizes a world in which anti-government citizens reject taxes and regulations, and “stop the motor” by withdrawing themselves from the system of production."
Ayn Rand was not anti-government, nor did her heroes "withdraw themselves from the system of production." They continued to be very productive - they just moved away.
"Ayn Rand’s philosophy suggests that average working people are “takers.”
False, and absolutely unsubstantiated. I've read most of what she wrote, and nowhere is this suggested.
"In keeping with Ayn Rand’s assurance that “Money is the barometer of a society’s virtue,” the super-rich are relentless in their quest to make more money by eliminating taxes."
Ayn Rand did not advocating hoarding money for the sake of money. To her, money is a tool for trade amongst productive people. It's the production that matters, and money is just one of the potential results.
She wrote: "So long as men live together on earth and need means to deal with one another—their only substitute, if they abandon money, is the muzzle of a gun."
"Ayn Rand’s hero John Galt said, “We are on strike against those who believe that one man must exist for the sake of another.” In his world, Atlas has it easy, with only himself to think about."
Someone hasn't read the book, because John Galt didn't have it easy. This particular quote can be summarized simply by saying "Let us live our own lives."
Totally agree. At best this rebase talk is navel-gazing, and at worst it's a technique that turns Git into a complicated, scary place for those just want to get work done.
I have introduced git and hg to many people, but I've always tried to tie it into what people do already. Without source control, practically everybody did the same thing: They'd work a little bit, they'd save, they'd work a little bit, they'd save... etc. Using branching for organizing work and a nice cheat-sheet of a few git commands, most non-technical people will be off-and-running.
It all works until the programmers make it complicated with the rebasing. The price of the tidy commit history is the loss of confidence of the rest of the team. I'd rather have the people.
Case in point: https://vimeo.com/60788996
Using Git can be easy to understand, as it takes only a few commands to make it usable. git commit, git add, git push, git pull, etc. That's enough to get most users, including people that would normally be afraid to use a command line, to a state where they can contribute to a git repo.
And if the work is being done in Github, then the person can use the Github apps to just-get-the-work-done. No command line.
What makes git hard are the men "helping" the woman in this video. Devs create these crazy rules around branching and rebasing, which results in:
1.) Hours wasted while people try to comply with a process they don't understand, and
2.) Timid work, as everybody's afraid that stepping on the wrong stone will trip a booby-trap that messes everything up, looping back to (1).
There is a workflow that people were following without git. They'd make changes, save them, and then move on. If someone else made changes, they'd bring those changes in (i.e. merge) and move on. In my experience, most people understand that. All of the rebasing nonsense is getting people nowhere.
A deep understanding of git should not be a requirement to use git anymore than I shouldn't need to know how my car works to drive to work. The goal is to get where we need to go, not to have the perfect vehicle and trip. Your git repo might get messy sometime, shrug, sorry -- development can be messy sometimes. Use the git experts abilities to clean it up, rather than try to get everybody to a git expert level.
Git experts: Keep. It. Simple.
Example? I don't understand what is meant by this.
"Extremely complex grammar, makes barrier to entry for implementation much higher"
Compared to... what?
If I only had a dime for the number of blog posts explaining what "this" means in Javascript...
Good luck with that.
I write automated tests (using TDD), and it's not an assumption that would end up in my tests. Testing would not force me to introduce the date as an argument, at least not in Ruby.
That's the thing about Ruby, or perhaps another true thing that can be gathered from DHH's post: Ruby lets you make the judgment call you're talking about, without sacrificing the testing. C# would.
So you'd say that this code is better:
post.publish Date.now
than post.publish
When the publishing will only happen now?I'm a Ruby developer who disagrees with DHH strongly on this issue, as well as his stance on SOLID and testing. I also have years of experience in C#, using TDD and using dependency injection and IoC containers everywhere. However, I think there's a point to be pulled from DHH's post about unnecessary ceremony around dependency inversion (the more important thing) and static languages.
If I were to write this "publish" method in C#, I couldn't even put it in the Post object. It all looks fine and dandy now, but what happens when the first wave of change comes in? Say, if we were to have to stamp an "updated_by" field? Then we get to this:
def publish(time, updated_by)
self.update publish_at: time, updated_by: updated_by
end
And so on, and so on. The dependencies have to be passed to the object, so every dependency flows up to become dependency on any object that uses it. And since having method calls like ".publish(Date.now, CurrentUser.name)" everywhere really stinks for readability and DRY, and since I can't make Date.now a constructor requirement to create a Post, I always found myself having to do this (in C#): public class PostPublisher
private IDate date;
private ICurrentUser;
public PostPublisher(IDate date, ICurrentUser){
this.date = date;
this.currentUser = currentUser;
}
public void Publish(post){
post.updated_by = currentUser.name;
post.published_on = date.now();
// save????
}
}
... and let the IoC container wire this sort of stuff up. Dependencies tied to this operation are isolated (as well as every other operation). But UGH, is this any better? So many classes and LOC just to do simple things.I just don't see a good solution to this, and I'm not satisfied writing "good" code that handling is a pain. I decided to try Ruby as it seemed to have answers for this, and it does.
You can call the ability to use the Date object and still change it a "global variable" or "linguistic flexibility," but the truth is: In the applications we write, published_at is only going to be set to Date.now and updated_by to the currently logged in user. And as soon as we write the application and deploy, it will serve the business needs wonderfully. As a C# developer, I justified the costs of doing these end-arounds as necessary to maintain a TDD'd codebase that could easily be changed later. As a programmer, though, I can't justify the costs of writing dozens of lines of code when I can TDD one line of code. And I sure as heck don't want to eat the costs myself. So today, I just do it with one line of code really fast and make the client happy.
He wrote: "As much static checking as possible: Static checking is good. Did you ever write a larger piece of code in one go, compiled it and it produced tons of errors? All these error would still be there, if you would not have static checking. You err much more than you think."
I think he errors much more than he really thinks. If errors are what he's truly trying to avoid, he'd be more focused on unit testing and TDD than passing syntax.
Descriptions like his make me wonder how many static typing proponents have actually spent any legitimate amount coding in a dynamic language for a production application. It seems all scary to code applications without a big IDE, but I promise that it's possible and a lot of people make it work.
"Use monkey patching in tests, never in production."
"Never" is a big word.
Years ago, I was tasked to change the text label of a file uploader. The site was built using a home-made framework on top of WebForms. It was even built to allow components to be replaced, but since everything touched everything else -- my simple task proved to be impossible. Even one of the original authors of the framework sat at my computer trying to show me, and after a couple hours even he gave up.
Compare that to a problem I was having with a Ruby on Rails site built on top of Spree from versions ago. I wanted to set up a staging server, and (for a reason that turned out to be my fault) I couldn't get the server to stop switching to SSL -- which the staging server didn't have. After spending a little bit of time to solve it, I just monkey-patched the SSL switch to false. Deployed, it worked, and I moved on.
We're really talking about edge cases here, but it's a symbol of a higher issue. Are we to be martyrs to past issues and bugs in code, devising more abstractions just to try to protect one code from another? Or is getting the problem solved in the most efficient way possible the better solution?
I'd use the phrase "it depends on the context" instead of "never."
"Native technology allows for excellent apps, whereas HTML5 apps will be at best just OK"
Sometimes "just OK" is what people want, and what meets the needs of the business.
The truth is -- building a mobile web app can be fast and can fill an iPhone/Android/Blackberry/Windows phone with the content and interactivity the business and users need and want. It can also be much cheaper. Different businesses have different values, and whatever works best to achieve those values is best.
Calling devs lazy for not learning native mobile languages seems like a cheap way to get clicks. New Year's Resolution: Stop clicking on them.
Maybe it should be titled...
"Why MongoDB Never Worked Out Two Years Ago When We Tried to Run It For Our First Time For One Feature, And Beside Another Database Which We Really Considered Production."
I've seen and used MongoDB on multiple projects, big and small, and it's fine. It's a database that stores data. Use it for that purpose and you will be ok.
It all comes down to testing to me. If the dev is writing a test first, questions about where things go are answered pretty quickly. If the tests become painful or awkward, you're probably doing too much in the code.
I think the common Rails response to painful tests is to stop testing. I've heard talk of the "diminishing returns" of testing, or debates of what deserves to be tested. I was once responsible for maintaining many Rails 3 apps that I did not write, and the story was all the same: Either there were no tests, or there were simple tests around simple logic, or there were simple tests covering one or two paths through some really complex logic. Once they felt the pain from their tests, they just stopped writing tests. What else are they going to do... challenge the "Rails Way?"
And this is the community that is supposedly known for their testing. Having used Sinatra or Rails for almost all of my web work for a while, let me tell you: The state of testing in the common Rails app is no different than I've seen anywhere else.
I think part of the drawbacks of multi-tasking is attitude. The multi-taskers I've known have taken their approach as a sign of their intelligence, as if doing just one thing at a time is below their capabilities. They act as if they've tapped some special, hidden potential of the human brain that common people don't understand. Yet despite their super-human powers, they're often one or two tasks away from completing everything they're supposed to finish.
Their work is best described as achieving "limit as work approaches done." They continue to work on something, they get closer to completing it, but you could give them an infinite amount of time and they'd never finish.
I'll take devs who can focus on one task and complete it.
They are not rare, there are CMS systems not covered in this blog post. On the Ruby side, take a look at the Ruby Toolbox to see many more content management systems: https://www.ruby-toolbox.com/categories/content_management_s...
It has the built-in "Well, there are a lot of CMS apps but not many used," but the other side of that is that there two (maybe three) very-popular and often-used content management systems in Rails that the author does not even mention. He claims to "spend more time looking at content management than most people" but then he has no knowledge of the most popular ones??
This statement is the biggest whopper:
"The existence and competence of Rails and Django have prevented a serious, shared CMS ecosystem from developing around either Ruby or Python."
I develop apps in Ruby and Rails, and it's the exact opposite. I use great systems like RefineryCMS or Spree to quickly get the framework of a site together, I pull from a massive amount of gems to get most of the functionality that I want, I reuse my private gems to get features specific to my needs, and.... at the end of the day, I only write what little code I need that is truly custom to the client's needs. I'd say that it takes some of the fun out of developing web apps if I wasn't happy being so productive.
The build-your-own aspect he mentions is true, though, but it's a problem with developers more than with the existence of Rails or Django. In my experience, many devs would rather work on their own because programming is fun and they want to solve problems like that -- and they want to be paid for that work. The way it usually works is, a dev will look at a tool, find some obscure reason why it "won't work," and then spend the time building his or her own. And since many managers don't have the knowledge to override bad developer decisions, they get away with it.
Sure, I'll expand on my reasoning, but only since you ask. :) I don't and won't debate IP here, but I'll try to give more details behind that short post.
Intellectual property rights, themselves, are more important than the monetary gain. The right to own the product of your work is incredibly important to the creator's life. If you make something, whether it be a wood carving, a sandwich, or even a computer program or piece of music, that thing is yours. To take that something from someone without consent is theft.
When it comes to intellectual property, the only way to control the thing is to control its distribution. If the creator has no ability to set the terms by which the book, song, software program, etc. can be used, then there's no such thing as ownership of the created work.
I think that's a worse loss than any temporary financial gain that could be had by the loss of IP rights, as those IP rights are everything to the creator. If a creator doesn't own what he creates, and he can't trade his creation on his own terms, how can he succeed in life? Where's that pride of knowing that what you made is YOURS and you can control it?
Imagine a situation where an accomplished, proud artist spends years painting what he considers his life's masterpiece. Then the next evening, a thief runs off with painting, but leaves a stack of $100 million in cash with a note that says "SOLD!". Was the artist justly compensated? Would there be articles written about how art theft could leave artists with more money than on the market?
If this was true (and I'm dubious of the "find"), it should be something for movie makers to consider when it comes to distributing their movies.
What this shouldn't be used for, though, is the default excuse by pirates when stealing intellectual property. "My theft actually helps, see?!?!?" Even if there is some financial gain, more is lost when the fundamental IP rights are stolen.
"Every 3 to 7 lines of code you'll find some amount of editorializing. Maybe every few hundred lines you'll find a good joke too."
I think there's the issue. In applications I write, every 3-7 lines of code is refactored into a method that is named exactly what it does, and every few hundred lines of code (usually much less) is in a separate file and class named on what he does. Broken out like that, there's not many places to put a comment that would be of any use.
But not broken out like that, of course you're going to need comments. But I think you'll find that comments aren't even enough.
"I know what the code says. But tell me the intent."
I think unit tests and expressive code work much better to achieve this goal.
Programmers.............