The Changelog: Software Development, Open Source - Rails 3.1 and SproutCore (Interview)
Episode Date: December 9, 2010Adam and Wynn caught up with Yehuda Katz to talk about upcoming changes in Rails 3.1, SproutCore, and his growing list of open source projects....
Transcript
Discussion (0)
Welcome to the changelog episode 0.4.2. I'm Adam Stachowiak.
And I'm Winn Netherland. This is the changelog week of where it's fresh and new in the world of open source.
If you found us on iTunes, we're also on the web at thechangelog.com.
We're also up on GitHub.
Head to github.com slash explore.
You'll find some training repos, some feature repos from our blog, as well as our audio podcast from this year.
Diddy, if you're on the Twitter, follow ChangeLogShow.
And me, Adam Stack.
And I'm Penguin, P-E-N-G-W-Y-N-N.
Episode 42.
You know what that is.
It's the key to life.
It's what it all means.
It's the meaning of life.
Yehuda Katz, the meaning of life.
Absolutely.
Fun episode this week.
Talked to Mr. Katz about JavaScript and Merb and Rails and SproutCore.
You know, I think that he knows a lot, wouldn't you say?
He's forgotten more than we've learned, dude.
I think he's coded more lines of code than I can probably ever look at.
You know, it's funny.
A couple of years ago at Lone Star RubyConf, I think you were there, 08,
I was set to give a talk on JavaScript and Ruby frameworks
and saw that Mr. Katz was going to be there.
And lo and behold, he was going to give a talk on JavaScript and Ruby frameworks.
And you didn't want to go in his footsteps, did you?
I did not want to play in his shadow, so what did I do?
I gave a four or five slide homage to Mr. Katz in varying degrees of hilarity,
and then switched over and did a talk on SproutCore.
And wouldn't you know it, he's going to go over to SproutCore.
Yeah.
Crazy. Lucky you, or lucky him. I know. So I's running over the Sprout Corps. Yeah. Crazy.
Lucky you, or lucky him.
I know.
So I'll have to do another presentation now.
He just keeps following my footsteps.
It was a fun episode.
Learned a lot about Rails 3.1 and the roadmap for the new version of Rails.
You know, I think other people will take more out of this than I will,
but the best part I personally think of this podcast
is when he's talking about SaaS versus less.
Yeah, I think you were getting all giddy there
when he was championing SaaS over less.
Oh, I was excited. I was totally excited.
And I actually had a follow-up call like two days later
with one of the contributors to Compass, a sister project to SaaS.
I was talking to Brandon Mathis and kind of mentioned a couple things in this podcast.
They're here.
And he was pretty excited about it.
Speaking of excited, got some exciting news out of the GitHub.
We got some awesome news out of the GitHub.
What is it?
We are now official partners of jobs.github.com.
That's true.
We are.
And we have two awesome jobs that we should talk about.
One from Gobbler.
They're a small focus startup that just came out of closed beta.
They're making a killer desktop application for the music industry.
Think Dropbox plus Lightroom plus YouSendIt.
And they're looking for a GUI desktop application developer
writing Cocoa or WinForms.
Wow.
So head to github.com slash jobs.
Actually, it's jobs.github.com, so I apologize about that.
Go ahead and check that job out.
We'll put this link in the show notes for this job.
Who else we got?
We also have something from RockMount.
Have you heard of RockMount?
I have not.
RockMount is this – they're reinventing the browser.
So it looks a little bit like Chrome.
It has some of the same kind of UI. Oh, I've seen that. Yeah. It's pretty intense. What about RockMod? engineer to be an integral part of their team, help them put streamlined development in process
with awesome developer tools and build the process to automation. So the position they're
actually trying to fill is a build, merge DevOps engineer. So if you're one of those kind of people,
head to jobs.github.com or go to changelog.com forward slash jobs and or see the show notes,
the best and most extensive show notes in the world.
Would you consider yourself a developer or engineer, Adam?
Definitely a developer, and I'm not an engineer.
I think to be an engineer, you have to wear a hard hat.
And is it yellow?
Probably, yeah.
With a big GitHub octocat on the side.
That's right.
That would be an awesome one.
Yeah, that would be tight.
They should sell us at the shop.
Yehuda is highly entertaining.
Should we get to it? Let's do it.
We're joined today by Yehuda Katz,
big name in the Ruby community.
For the few folks in the
Ruby community that may not know who you are,
and maybe for the guys in the Python and other circles. Why don't you introduce yourself and just kind of give you a little bit about your background.
Sure. So my name is Yehuda. I've been doing programming work-ish for about five years.
Most of that time has been some combination of Ruby and JavaScript work. Started out mostly
with JavaScript, but quickly got into Ruby
and
joined the Rails core team a couple years ago
after about a year and a half of work on MIRB,
which was a project that got merged into Rails.
Joined the jQuery team
about four years ago, and just joined
the Sprout core team. So essentially
my work historically has been
web technologies,
doing things with the web stack. And I've sort of moved around a lot of different parts of that.
And these days, I'm focusing a lot on JavaScript. The last couple years, I focused a lot on Ruby,
but I use both technologies pretty much all the time.
So I guess moving from jQuery to Sprout Core, does that go against the grain a little bit?
So actually, not really. I should give a little bit? So actually not really.
I should give a little background.
So Carl and I, Carl worked on Rails 3 with me
and now works for this new company that I'm at called Strobe.
We actually had started looking at building our own framework
for doing mobile stuff,
mainly because we didn't really know what was out there
and it looked like there wasn't a lot of good solutions.
And we had spent a bunch of time
thinking through some of the problems
and we put together some code.
And I saw that Charles, who started SproutCore,
had left Apple and he wrote this blog post
that essentially said,
technologies in this space really need to be free
and open source and not only that,
but the tooling around it needs to be open source
and people who are
trying to essentially get build things um and make their business model licensing uh licensing of
software aren't really getting it and that really resonated with me it was sort of the same thing
that i felt when i was building this other framework with carl um we called it momentum
that's lost the history i guess and when I pinged Charles
one of the things I was definitely concerned about
since I was a member of the jQuery core team
was whether or not it was going to be okay
and what I learned quickly
was that SproutCore had recently
sort of switched over the entire view layer
to use jQuery
so before I even joined
the entire view layer SproutCore uses jQuery
and what's important is that SproutCore uses jQuery. And what's important
is that SproutCore itself is really just
about providing abstractions
for the model and controller layers,
acknowledging at
this point that jQuery is basically
the standard library for the things that are
the Vue layer. So if you're building,
if you're doing a lot of DOM work,
you should use jQuery, and SproutCore
agrees with that assessment.
So it's more about adding things, adding more abstractions.
It's not really about competing with jQuery.
One of the abstractions that Rails had early on was, I guess, RJS templates and things of that sort.
There tends to be, I guess, a subset of the Ruby community that really doesn't want to touch JavaScript. How is SproutCore familiar for the Rubyist that wants to come into a JavaScript framework?
So I'll actually not answer your question, but I'll try to answer it.
I'll try to answer the spirit of your question.
So actually, one thing I think people get into trouble with when they start looking at quote-unquote MVC frameworks,
SproutCore is a quote-unquote MVC framework, is that there are a lot of people, myself included,
really learned the MVC pattern in Rails. And the MVC pattern in Rails is trying to deal with the
fact that even though the MVC pattern was built for a stateful world in HTTP, we only have a
stateless world. So it's sort of a modification of the traditional
MVC pattern. And it's
actually a simpler version of it, right?
Because you're not really worrying about state,
you're just worrying about, I have
a request, and you are dumping out a
big glob of something, and that gets rendered
by somebody else.
And the amount of state
that is involved can vary,
but relative to like a rich GUI application,
it's actually very small.
And I think there's a lot of people out there
who have gotten used to that mode of MVC.
They don't really know any other mode of MVC,
and so they're building JavaScript frameworks
that essentially emulate the mode of,
here is a route, I have gone to the route,
now I'm going to create a blob of HTML
and insert it into some content area.
And I think that actually that is,
those things are, while they,
I think they can,
I was going to say they're doing a disservice,
but I actually don't want to say that.
I think they're really good for people
who are used to Rails
and they want to dip their toes
into building applications
that live more on the client side.
But I think that the more traditional MVC where you have stateful views, you have a
controller, you have models, all of this lives in a world that is fluid with rich interactions,
that is actually more along the lines of the MVC that you want on the client side.
So I think, I guess what the easy answer to your question is, people who know Rails will find themselves at home in SproutCore because it's MVC.
But what I actually want to not answer that, I actually want to say, don't actually think it's the same MVC.
If you try to apply the MVC paradigm that you know from Rails into SproutCore or Cocoa or Windows GUI programming or any kind of rich GUI programming, it's going to be confusing.
And I think it's useful
to sort of step back
and relearn MVC
for stateful applications.
Yeah, MVC is a pattern
that's beyond the web.
I guess more where I was going with that
was that it's distributed as a gem
and has generators.
Yes.
So in terms of tooling,
there's a lot about SproutCore that cool i'll i can talk about that um so uh first of all sprout core
was originally built as an extension of merb which i worked on um it doesn't it isn't distributed
that way anymore but it sort of has a heritage of trying to get to a convention over configuration
approach um which i want to get back a convention over configuration approach,
which I want to get back to in a minute,
because I think people might, if they try to use it,
might be annoyed by me saying that.
So it tries to achieve some of the similar approach.
It tries to have generators, conventional locations to put files.
Pretty much all the tooling is written in Ruby so there's a server that runs
and that server
is a rack application
and actually something that I think is really
interesting is that Rails
applications have a development and production mode and I think
it's pretty intuitive to most people who do Rails that
there are things that you want
you want things to behave a certain way in development and you want
things to behave a different way in production
production you mostly care about performance
in development mode you mostly care to behave differently in production. Production, you mostly care about performance. In development mode, you mostly
care about the speed of development.
So things like reloading are very
important to a Rails app in development.
In production, you're willing to trade off speed.
A Sprockler analogy
that's similar is in development,
you actually don't want to combine all the files into
one file because you want to get errors
that have backtraces pointing at the file.
In production, you want to combine the files.
It's actually important to have different
development and production mode. The only way
you can achieve that is by having something
that knows the difference and decides how
to serve your page
differently. The traditional
way of handling this is to not have a build
tool and manually
roll your own development mode and manually
roll your own production mode.
But that sort of relies on you being a one-man bomb squad, right,
figuring out what the right tradeoffs are everywhere.
And just like in Rails where it's actually not good for you to have to think about that,
in SproutCore we also agree that it's not good to have to think about that.
And so there is a server, which a lot of people are put off by, because they're like,
oh, I'm writing JavaScript, I'm used to throwing script tags
in, but it gives you the ability to
have really tightly
refined production mode, tightly refined
development mode, and not have to think about it at all.
And like you said, for people
who know Ruby, it's distributed as a Ruby
gem, works kind of the same way
as Rails. You do gem install SproutCore,
the gem comes with all the code in as Rails. You do gem install SproutCore. The gem comes with
all the code in it that is needed.
The JavaScript code
that is needed as well as the build tools.
And actually, what's cool
is that the gem,
you can actually have other gems
that have other JavaScript codes.
There's a company called Eloqua, which is
a big SproutCore company, and they have distributed
some other libraries as gems. The SproutCore company, and they have distributed some other libraries as gems.
And the SproutCore build tools will try to find other SproutCore gems
and make those things potentially available to the build process.
And this all feeds into a larger plan that we have to sort of make,
to create a place which is not,
there happen to be some SproutCore gems on rubygems.org,
but like here is a repository that is for SproutCore gems
because our build tools are already designed
to handle gems essentially containing JavaScript code.
And so there's a lot of cool stuff you can do
that you can already do, right?
But there's a lot of cool stuff
that you can really surface and make visible
by creating a gem repository, which is just for SproutCore gems.
A few months back, you released Handlebars.js, September.
Yep.
Since we're talking about views, how does this fit into SproutCore?
Yeah, so I should actually go back.
I had meant to say that to talk about about the convention of a configuration. So I think
SproutCore gets a lot of things right in terms of conventional configuration and gets many things
wrong. And a lot of the reason for that is that Apple did a bunch of work on R&D essentially in
SproutCore. And so there's a lot of features in SproutCore that are mainly designed for
internal Apple apps. And there's like some layer of glue code on top that exists inside
of Apple that never became part of the open source project. So the underlying code is
really powerful, but figuring out how to use it is maybe difficult. And this is especially
true, the most clear example of this is the SproutCboard datastore, which is like this crazy powerful
ORM that's
backend agnostic and does
all kinds of cool stuff, but
figuring out how to write something that just
makes an AJAX request to a Rails app and then
gets results back and puts it into the datastore
is a complicated process.
And so something
that I am going to be doing
in general is figuring out what the right conventions are.
So the clear win in the case of the data store is to make a higher level abstraction that deals with making requests to URLs,
but still making the lower level one available for people who, let's say, want to get their data out of local storage
or want to get their data from some other mechanism that's not just hit a URL, you will get
JSON back, right? So I think it's really good. Like, the first thing I saw when I looked at
SproutCore, I guess, a few months ago was the primitives here are rock solid and amazing,
and the API is uneven. Sometimes the API is really good, sometimes the API is too confusing. So
I got into this spiel because you asked about handlebars. So I actually released handlebars initially
or I started it before I even got involved in SproutCore,
mainly because I actually really liked the ideas of Mustache,
but I found that I was constantly taking JSON
that I put into Mustache and pre-processing it
because in Mustache, you're always in a context,
and if you want to get something from another context, you can't.
So what people will usually do is they'll go in,
and if they want something from the root of the JSON document
to be available to a child of the root,
they'll go and copy that element in,
and then it will be available when you're in that context.
Handlebars does a lot of things,
but probably the two motivators were
make it possible to use arbitrary paths.
So instead of you are inside of a document
which has a list of posts,
and it's a blog post with a list of comments, right?
And the blog post has a title and a body,
and the comments have, you know,
let's say also a title and a body and an author, right?
I want to make it possible,
if you're inside of a comment,
to go dot dot slash title,
and you get the post's title.
You can do that from anywhere,
so I added support for arbitrary paths.
I also added support for parameters and helpers,
so helpers can take these paths as well, so you can start passing context into other helpers. So helpers can take these paths as well.
So you can start passing context into other helpers.
And probably the most important thing
and the main motivating factor, actually,
was that block helpers.
So Mustache has a concept of block helper
where if you do pound and then a thing that's a function,
you get the body from the inside as a parameter.
And
what I did
is that instead of getting
just the body, the rendered body,
you get a function which you can call with a context
and then that body
will get executed as though
it had that context in the first place.
So it lets you
do things like pound list some context,
and then you can, in your helper,
you can iterate over that list,
and then, you know, say ul plus,
and then iterate over the list,
and then for each item,
call the function with the item,
and then concatenate, right?
So it lets you do much more powerful block helpers,
more along the lines of what you can do with a Rails block helper,
which is actually the motivation.
And all these things together actually make it
so that you rarely have to do any kind of crazy preprocessing on your JSON.
You can actually...
You still get the benefit of mostly logicless templates, right?
So there's no arbitrary code in the template at all.
But what there is is a lot more powerful mechanism for moving around.
So essentially, I did this sort of because I liked mustache and wasn't happy with mustache.
So I liked the core idea, like the principles.
If you're going to write down design principles of mustache, I would agree with them.
But I felt like you could push the envelope a little further without violating the principles. If you're going to write down design principles of Mustache, I would agree with them. But I felt
like you could push the envelope a little further without
violating the principles of Mustache.
And then when I
joined SproutCore, probably one of the
biggest problems that I saw
in terms of API was that
the way that you make HTML
in SproutCore is
by creating strings and
concatenating them onto a context.
And while I think that is very useful for small,
like a checkbox, sure, you should do that,
making a template with a lot of overhead.
If you're going to build something where you have, like,
a big view that you're going to build yourself,
like, if you're going to build a blog,
you might have two views,
so a list of, like, a sidebar and a main body area.
And those things are templates.
Those things are not little views that you'd want to just build up HTML strings.
So I thought about using HandleWash for that.
And then the most exciting thing about what I'm trying to do is that I've –
the thing that really frustrated me about mustache is it seems like you
have all the information that you need in a mustache template to update things as things
change. So let's say you put in that blog post and then the original object, so the original body,
changes for some reason. Or you add a comment. So let's say you add a live comment
to the comments array that you originally used to populate the template.
It seems
like, because of the fact that
these templates are logicless and are all talking about
like context,
it seems like you could just somehow figure
it out and update it without having to go magically
update it. And the way sort of most people do this,
the way like Backbone does this, is it just
essentially assumes that you're just going to re-render the whole
thing. Which, again, it's
more like how Rails works, right? It's more like
we're going to take a huge blob of HTML
and replace the old blob of HTML.
But that's not really great.
Ideally, you want to be able to update little
pieces and not have to update huge amounts
of HTML.
And so it's frustrating that
it looks like we have all the information
we need, but really nobody does it. And so it's frustrating that it looks like we have all the information we need, but really nobody does it.
And so what I'm currently working on adding to Handlebars is a bind helper,
which lets you essentially say, find this area of code here to this piece of the context that I'm in right now.
And so the way it will work will require some kind of object-binding system.
SproutCore has a really, really, really good one that is probably the best way to do it.
jQuery has jQuery DataLink, which is less powerful,
but will also be able to be used.
And basically the idea is that as you're creating your template,
you can either make static content,
or you can say this chunk of code here is actually bound to this object and by the way if the object changes and um handlebars doesn't care how it
changes handlebars just will essentially invoke a method that lets the data linking system set it
set this up but by the way when this changes come back and update this code. So I think, like, to me, there are things that we can do in JavaScript to improve, to make things more, like, more
stateful and make things less about, like, throwing huge blobs of code on without really, without forcing people to think about a lot of boilerplate, right?
In this case, you're essentially saying, let's say this is the blog's title.
If you update the blog's title, you have essentially already wrote the code.
So this is sort of like what a lot of people like about Rails, right?
It feels like you don't have to say the same thing a lot of times.
And that's what I'm trying to get at with handlebars is make it possible to do things
so that it's not just this huge blob of code of HTML,
but at the same time you can treat it like it is.
You can almost think about it like I'm just writing a template with a blob of HTML.
I'd like to switch gears back to Rails for a moment.
In Rails 3, so before we get to Rails 3.1 and the roadmap, in Rails 3, what are the big chunks of maybe standalone pieces of functionality that maybe together are greater than the sum of Rails 3, like Bundler and some other things that went into the project?
Sure.
So there's a few good answers here. my favorite thing that we did in Rails 3, or our favorite two things, are we completely rewrote
Action Controller, and
we wrote it in a much more modular
fashion, and I'm already
starting to see a lot of plugins and
functionality that is
existing in the community that's taking advantage of it.
So even though, when you look at Rails
3, it looks like, oh,
nothing really happened here, it's the same
functionality. I guess it's a little better internally.
The fact that we essentially went
from one huge monolithic object to a bunch
of little objects means that
people are actively
being more aggressive about what
things they're willing to do because of the fact
that there are more cleanly defined
objects that are handling things.
And more things that are
explicit, like, you can modify this,
and we promise to keep this feature available.
The other thing that is sort of along the same lines
is we completely rewrote RailTies,
and that created a much better mechanism
for hooking into different parts of Rails.
So an example of this is like ActiveRecord right now
is a standalone gem that has a few files that are
called the rail tie, which is the code that hooks into the rest of Rails. And ActionPack actually
doesn't know anything about ActiveRecord. All it knows is that it has exposed some APIs for people
to do things like add things to the log, right? So for instance, you have a log and it says model
time one second, or hopefully not one second, hopefully like 50 milliseconds or 10 milliseconds, right?
And that used to say, if you're using ActiveRecord,
do ActiveRecord base dot something, right?
It's like this global thing.
And now in Rails 3, there's just an API for anybody can add stuff to the log.
Here's how you do it.
And ActiveRecord hooks into that.
And the really great thing about this is that there's all these other ORMs,
like, you know, Mongoid and DataMapper and the SQL ORM and Cassandra Object.
And they can all do the same thing.
They can all hook into these pieces and change ActionPack
because they know that this is the API.
And they can actually look at ActiveRecord
and look at the code that ActiveRecord is using to hook in.
So it's not even like there happens to be an API.
It's like we have isolated the code in ActiveRecord
that actually does that hooking into the API.
So I think all these things sound good in theory.
What's happening in practice is that people are,
the plugin ecosystem is getting a lot more feisty.
People are actually writing plugins
that in the past people would
have been scared of. People would
have grimaced at because they would be
doing black magic and now there's not so much
black magic and you can actually do really aggressive
things and I really
like that. I think that
that has been the weakest, hilariously,
right? People say plugins are the
biggest strength of Rails.
I think that that's true, but I think plugins are also a huge weak point
because every upgrade of Rails results in invalidating a huge amount of plugins
in very problematic ways.
And I think while Rails 3 is not a panacea for that problem,
Rails 3 really creates a much more solid ground for people to go and aggressively do things with Rails.
And we're already starting to see some of the benefits of that.
What's on tap in Rails 3.1?
Okay. the biggest, the most important conceptual change in Rails 3.1
is that we've gone from having a bunch of caching ideas
that you can use in various situations
to pushing a lot more towards using the HTTP caching system.
So we've had for a very, very long time
helpers that let you set e-tags,
that let you set the last modified headers.
But people couldn't really make use of those things.
Those things were not very useful, except that we've gone to using HTTP caching
as sort of like the major caching technique
that people will use.
So if you say, for instance,
Rails has this feature where you can say stale?
and then pass an active record object,
and that will basically tell you whether or not,
based on the headers that have been pulled in,
whether or not you need to serve the new thing.
So basically, if you say headers that have been pulled in, whether or not you need to serve the new thing. So basically,
you say if stale, etag,
and then some post, and then
have a block. And basically
what that will mean is, if it's stale,
do this stuff. Otherwise, no, just say
it's fine.
And obviously, we need to write a lot
of good documentation about how this works.
But basically what this means is that now
you can do that same thing, and
Rails has a built-in HTTP caching
layer that will also
handle, do the right thing
in terms of
page caching or
action caching.
We're not really taking away
the old features, although we're plug-in-izing
some of them. But it's
sort of the same,
and I'm actually doing a really bad job of explaining it.
I could do better by showing code.
But it's sort of a similar conceptual shift as the conceptual shift to REST in the first place.
It's the flip side, right?
Rails 1.2 introduced REST as a request paradigm.
Rails 3.1 introduces REST as a response paradigm.
And while I think it will probably meet
with a lot of the same reaction
as the original REST for requests met with,
which is, I don't understand the point of this.
This seems to add complexity.
But I think that it will result
in a lot of the same benefits
of simplifying how people think about applications,
making everything use the same concepts,
and making it possible for Rails itself
to start funneling things through the same concepts, right?
So the fact that there's REST as a request paradigm
means that there's all these things,
like you can render an object,
you can redirect to an object,
you can link to an object,
you can make a form for an object, right?
These things actually come out of the fact that Rails uses REST as a request paradigm.
And I think that as we move forward, we'll have a lot of the same epiphanies
in terms of the response as we use HTTP and REST as a response paradigm.
So it's hard for me to sort of give you a big blazing, here are the big wins.
It's sort of more like we are using the right architecture
and we believe that it will result in good things.
And then the other really big 3.1 feature
is that we're getting asset compilation
into sort of the normal path of Rails.
So you can obviously install SAS now or Compass
or things like this or Sprorockets, and they can interact
with Rails and result in some compilation of your CSS. Rails 3.1 makes that a first
class concept. So in the same way that you can have post.html.erb, you can have post.js.erb or post.js.coffeescript or post.css.scss or post.css.sass.
And basically taking the whole asset chain and making it like the rest of Rails,
making it a first-class app concept.
So that's really exciting.
It's actually been really hard to get it, to think about how to make it work.
I think a lot of the motivation actually was to make things work correctly on read-only file
systems like Heroku. And when you start thinking
about solving this problem for everyone who uses Rails as opposed to the people
who opted in to the specific feature, it becomes really hard.
And there's a lot of weird edge cases, little edge cases, and
probably my least favorite thing about all this is that
almost nobody who uses Rails relative to the whole population
actually is like a sysadmin and is going in and modifying their Nginx.
So I think a lot of people listening to this podcast probably are doing that,
but most people who use Rails are not actually doing that.
So if we had a good solution
that required that people go and modify something about their deployment, that would not be okay.
So we need our solutions to actually work totally inside of Rails, and that has been somewhat of a
challenge, but it's, I think, a good constraint. It makes us really think about how to build
the tools that we're building in a self-contained way
and in a way that pretty much everyone who uses Rails can take advantage of and get benefit from.
There probably will be some things where if you actually go and modify your Nginx,
you might get better benefits, but the goal is to make it so that no one has to do that,
and it still works.
How far does the format support go for that asset compilation?
Is it a public API I can tap into to support future formats?
Yeah, so actually the really cool thing about it is that it uses exactly the same API as regular template handlers.
So you could theoretically do foo.js.haml, although that wouldn't actually make any sense.
But ERB, for instance, will be using exactly the same template handler as the regular ERB template handler in the same context.
So it's just, it's basically just a regular, a regular page.
And if you want to do CoffeeScript, you would essentially look at the 20 template handlers that exist and write a CoffeeScript compiler that comply with that interface.
You mentioned, uh, SAS and Compass, uh Compass as it relates to Rails 3.1
and the support for that,
but I'm curious
as what your opinion is
of SAS, Compass, Haml,
things like that
and what they've done
for the front end.
Sure.
So SAS and Compass,
actually,
we've been going back
and forth on this,
but there's a pretty good chance
that we'll have built-in support
for SAS in the same way that we have built-in support for Sass
in the same way that we have built-in support for ERB and Builder.
And the reason for that is that Sass, and specifically SCSS, really sticks out as
the best compilation toolchain for Ruby that exists for CSS.
SCSS, I don't know if people know this, but SCSS is a 100% compatible superset of CSS.
So if you take a CSS file and put it into SCSS, it is guaranteed to continue to work.
That is actually not true about the LESS project.
It kind of, they want it to be true and they market it as being true, but there's a whole bunch of edge cases that break. And so the fact that SCSS can take in an input
of any CSS file and give you the same
output means that it's possible for Rails
to sort of make it the default because
it's kind of a no-op if you don't use the features.
But then we can start doing things
like add spriting support, which we're going to ship
with Rails 3.1, that
now you just sort of like an extension
to CSS. You can modify your CSS file
and now, boom, you have Sprite in support.
You want to use CSS3 border radius,
and you don't want to have to worry about the exact syntax.
Boom, there's a helper that you can use that comes with Compass
that lets you do that.
So I'm actually, I think that CSS, the SCSS in particular,
is really exciting for that reason.
I think the fact that you particular is really exciting for that reason.
The fact that you can sort of use your regular CSS and then opt into features as needed,
and the features look like regular CSS.
They've actually given a lot of thought to making the features look like CSS,
but not potentially conflict with future CSS features.
And I think that's great.
I think Haml is sort of more of a mixed bag.
I personally like Haml. I think Hamill is sort of more of a mixed bag. I personally like Hamill.
I use Hamill a lot, but I get why some people want to see the HTML in front of them while
they're designing.
Um, there are times when I'm doing simple things where I feel that that is the case.
Um, yeah, I agree.
I think there's times I'm writing Hamill and HTML.
It's, it's like, I'd like to write the, the HTML in some cases.
And that's kind of when you dip that into a filter.
But Haml, if you're dealing with conflicts and tags and in the ERB context,
there's lots of issues when you deal with conflicts
that like today I spent 45 minutes dealing with a conflict
because I was working in ERB and I was like, this sucks.
I agree.
I think that's probably the best thing about Haml
is that it makes it so that, like,
grabbing a bunch of lines from a Haml template
is mostly like an atomic operation.
And that is not the case about ERB.
So in general, I like Haml.
Mainly for that reason.
I like being able to copy and paste, like,
chunks of code into somewhere else
and know that I didn't, by mistake, forget an nthag
and now I'm screwed.
The thing is that SCSS is a bigger deal, though, because SCSS fundamentally transforms how
CSS works.
It lets you actually write functions in CSS, and that is a big deal.
I think that's something that everyone knows is missing from CSS, and it does it in a way
that feels like CSS.
So I think that's good.
That's like a bigger win to me than, than Haml.
You mentioned less, um, in your answer there too. So it sounds like you're
leaning more towards SAS and specifically the SCSS syntax that they have over less. Is that true?
Uh, so I have to be honest. I personally am extremely biased towards projects that have
been around for a while. Um, specifically projects that have been around for a while. Specifically, projects that have been around for a while are under active maintenance and have gone
through a bunch of upgrades to the underlying technology. So people who have
successfully upgraded their stuff from Ruby 1.8 to Ruby 1.9, from Rails 2
to Rails 3, that gives me a lot of confidence that they'll be
around for a while, that they'll keep going. And I generally
tend to be a naysayer when it comes
to the new hotness um because like with less uh these things oftentimes end up getting abandoned
when the guy who wrote them gets tired of it that actually happened with less he decided like oh i
would rather write a javascript version of this so less r RB is now abandoned. And I feel that happens often,
and I'm willing to stick with something
that is a little less shiny, but more maintained,
even with all its flaws,
then jump right on the new thing with the new syntax
that maybe has a better API,
but hasn't proven itself in the market yet.
So I think it's good that some people don't do that, right?
Because somebody needs to test it out.
But if you were,
to the world,
if you're building
something that's stable,
I would give,
I would not go with
the way that Ruby
is oftentimes
evaluate these things
which is sort of like
what is the best
possible API here?
I would more,
I would say I want
a good API
but I would promote
stability and long-term
maintainership
and ability to get past milestones in the underlying technologies
above where most people normally think of them as.
So the reason that, I mean, nobody should use less RB.
It's actually abandonware now.
But even back before it was abandonware,
I would not have used less RB, the Ruby version of less,
because it just wasn't't it hadn't actually
it's not about maturity it's not about like does it have bugs it's more about like the maintainers
haven't really proven themselves yet so the last couple years of your life you've been working on
rails 3 handlebars thor bundler i'm just curious when you actually sleep in all that time with all
that work you're doing? I try to sleep.
Actually, the answer to this is interesting,
which is I spend a lot of my time trying to think of ways to help other people do work.
So obviously I can write a lot of code.
That's great.
But I think I'm more effective
when I'm helping other people write code. So
a lot of my work on Rails 3, more than like
half of my time probably, was spent cultivating
and nurturing new Rails core team
members. So
I worked really closely with Aaron Patterson,
with Santiago Pastorino, with Jose Valim,
with Xavier
Noria, and a bunch of other people that
have started since Rails 3 to
cultivate them.
And so I end up looking more productive than I actually am.
And a lot of my projects, like Handlebars.js, I have to give credit to Alan, who basically picked up the project after I spiked it out and got it through sort of its teenage years.
And with Thor, Jose Valim has been sort of, uh, maintaining it for a
while.
So I, I think that's something that more people, as you become somebody who gets more productive,
you could obviously keep building everything yourself, but I feel like there's a lot of
utility in, in nourishing other people.
And that's something that takes your time.
I think it can, it can be draining and it takes up time, but it's much more productive in terms of total output
than trying to do everything yourself.
And you have to give up thinking that the things you're going to create
are going to be perfect,
because obviously you're not writing them anymore.
What were the big lessons that the Merb Rails merger taught you?
Actually, the thing that I just said before,
which is that people should give more credit
to things that are mature.
So I think MIRB was on a good path,
and it would have been good.
But I think that Rails,
like things like RubyGems and RDoC
and Sass and Haml, right? Rails like things like RubyGems and RDoC and and
SAS and Haml, right? These things
that have been around for a while, there's a lot of wisdom
in these things. And it's very
popular for people to sort of
say, oh, I can rewrite that in a weekend.
And they'll go start cranking
it out. And they don't
think about the fact that RubyGems
runs on every platform that Ruby runs on. They don't think about the fact that RubyGems runs on every platform that Ruby runs on.
They don't think about the fact that
JRuby has spent a lot of time making
RubyGems run for JRuby.
They think, oh, I can imagine writing something
that will work for my exact use case in
a day, and then they go do it and release it.
And the Ruby community is
a fickle bunch and will
sort of hop on that thing
very quickly. The guy, because he only did it in a weekend,
actually was never committed to maintaining it in the first place.
Bundler was actually in a similar situation.
Bundler is really robust. We spent a lot of time on it.
They're occasionally competitors, but they're not serious competitors.
They're not people who are really committed to making it work on every platform.
They're not people who are committed to really maintaining it.
And so I guess what I learned from the merge
was that people should give more credit to this.
People should give more credit
to the wisdom in existing code.
They should be willing to spend more time refactoring code.
I think in general people are much more willing
to start a whole brand new project
than to refactor existing code.
And they underestimate the amount of, I guess, wisdom that is in the code bases that exist in the world right now, especially if those code bases run on a lot of platforms. I think
that's an underestimated problem, making your code work on Windows. So if something works on Windows,
you should probably refactor rather than rewrite, unless you want to be dealing with Windows
bugs for the next several years.
So you're pretty
accomplished in both the JavaScript and the Ruby
circles. Do you ever cross over and do JavaScript
in the server?
I'm actually interested in that.
I'm less interested in
Node.js, although I've been playing with it
a little bit recently, mainly because
I think that the cases where evented programming on the server is useful
is a narrower list of cases than people think.
So I think, for instance, if you're building a chat server, sure, you should be using Node.
I think there are characteristics of JavaScript that make it really good for evented programming.
The most important characteristic is that every single function is a closure. So if you define a variable
anywhere up the chain, it's going to be available everywhere down. So you can do nested callbacks
and things will work. In Ruby, methods don't have that characteristic.
They're hard boundaries. And so you have to think about things a little bit
more. So I definitely, I like JavaScript a lot for evented programming.
But I think that there's a lot more cases that are not evented than the evented zealots would like to believe.
So if you're building a chat server or anything involving push, absolutely, I think Node.js is a really good option.
What I think is a much more interesting and better use case is I've been, so in handlebars, I've been, I've actually been rewriting it
recently because I had some issues with the stuff I
talked about earlier. And I actually have been using
sort of quote unquote server side JavaScript tools to develop it because
I would rather develop something like
handlebars, which isn't really DOM-bound,
on the command line using tools I'm familiar with,
than have to fire up a browser
and look at DOM nodes that tell me
whether my tests are passing.
And so I'm really interested in RubyRacer,
which is a Ruby binding to V8.
It's a really amazing Ruby binding to V8, actually.
I managed to get the handlebar queueUnit test running through RSpec with it.
So crazy.
Like, the technique I use is pretty crazy.
But essentially it boils down to the fact that you can expose Ruby procs into JavaScript as functions.
And then you can capture functions in Ruby land and call them.
And so I was able to sort of expose functions into JavaScript
like the test function in QUnit,
which would capture the function,
and then I was able to have RSpec run it
with the proper name.
So I have RSpec output for my QUnit.
I think things like that are really exciting.
Being able to take server-side JavaScript like V8
and run it inside of contexts that we're more familiar with.
Yeah, we covered RubyRacer on episode 023.
Charles recently wrapped handlebars in the RubyRacer
and has handlebars RB, which is not a port.
It's just a wrapping, right?
I actually really like that approach.
I wouldn't mind if someone did a real Ruby port of it,
but I like the fact that it's so easy.
I mean, I worked for a long time on another project called Johnson,
which is a SpiderMonkey binding,
and honestly, SpiderMonkey is just a bigger mess than V8,
but I ran GemInstall the RubyRacer,
and it actually built without any complaints,
and it never segfaulted,
and all the bindings work perfectly.
I get, you know, JavaScript.
My backtraces have JavaScript in them.
It's just really, it feels really solid.
I mean, I was looking at the code.
There's a lot of Ruby code there,
so I don't really know if it's really solid.
It looks good, but it feels really good
compared to other approaches that I've used in the past.
Thoughts on CoffeeScript?
So I feel like one thing that the browsers need to do in order
to make things like CoffeeScript viable is make it easier to tell the browsers the source of
compiled files. So the reason I would not use CoffeeScript today is because there's no runtime
with a debugger that runs CoffeeScript. So you have to rely on the fact that
the CoffeeScript code,
the emitted
JavaScript code is close enough to the CoffeeScript
code that if you have a bug, you can sort of work your way
back and figure out where the problem is.
And JavaScript is already hard enough
to debug. Compared to Ruby,
it's like a nightmarish debugging environment.
Adding that level on does not seem good to me.
I think that problem is actually solvable
if JavaScript, if browsers provided a commenting format
that let you say, these three lines here
came from this line in this source file.
Then you would actually get the backtraces
could contain information about the original source file,
which also, by the way, would be really useful
for minification and concatenation, right? So that you get real backtraces could contain information about the original source file, which also, by the way, would be really useful for minification and concatenation, right,
so that you get real backtraces.
It's something that I keep meaning to sort of propose to people in the browser world.
But I think until something like that happens,
you end up with it becomes really too hard to figure out what the generated source is.
On the flip side of that, I actually like the CoffeeScript syntax.
In general, I'm not a huge fan
of white space sensitive programming languages,
but that's not really, that doesn't matter to me.
CoffeeScript is pretty nice.
And if there was a debugging environment
that made sense and didn't cause me to gnaw my eyes out,
I would probably give it a serious attempt.
Got a series of A, B, or none of the above questions for you.
Bash or ZShell?
ZSH.
TextMate, Vim, Emacs?
Vim.
MVim.
jQuery or Prototype?
jQuery or prototype? jQuery.
This is where we turn it upside down and ask you what's on your open source radar.
So what of your own projects or other things out there have got you excited
that you want to hack on in your spare time?
Yeah, good question.
I'm actually working on a lot of things.
Probably the things that are on my radar for working on are mostly documentation.
So I have actually cranked out a whole bunch of stuff, and other people have as well.
And I feel like there's a lot of missing hidden gems in the stuff I've built, like Thor in particular,
that if I just spent like a week or two weeks making a site that was like the Bundler site, I think it would unlock a lot
of interesting possibilities. And I think
in general, I'm pretty conscientious about documentation, but
I end up creating a lot of things that don't have good enough documentation.
I'm also working on a whole bunch of Ruby stuff
with Carl for the projects we're working on at Strobe.
There's a project called Picard.java, which is an asynchronous web server,
which includes an asynchronous middleware API, which is pretty nice,
that we're maybe going to use internally and has already sort of been released,
and a whole bunch of other things along those lines
that are more for internal use and people can peek at them.
So I guess there's a whole bunch of random things,
but nothing really new.
There aren't any projects that have sort of piqued my interest.
Actually, I'm lying.
Libgit 2 looks really awesome.
Yeah, so I should backtrack.
So until like two days ago,
I was mostly sort of dotting my I's
and crossing my T's on my own projects,
documentation, stuff like that.
Libgit 2 looks really interesting.
I think the thing that's great about it
is that I think it opens the door
for people to build more interesting things on Git.
Consider this a challenge to the world.
It would be great if there was a Git library that worked with arbitrary backends.
So right now, the Git protocol is really simple.
It's a key value store, smart, et cetera.
There's no reason why you couldn't put the Git protocol in like Redis or MongoDB or React or something like that.
But the way that the Git libraries have been organized
until now made it a hard task.
Lib Git 2 would make it an easier task
because even though it's still sort of oriented
around the file system,
it's first of all better organized
and second of all, it's actually something you can around the file system. It's, first of all, better organized,
and second of all, it's actually something you can create as an open source project
and then have a linking exception to their GPLS,
and so you can use it in something proprietary
so people might actually be able to spend company time on it.
So that's actually really exciting to me.
It's something I read a bunch of the code when it came out.
It looks really interesting.
I'm just in general excited about the fact that there might be a way
to gem install something on Windows and actually have it do git things
without it relying on some git binary that was installed in your system.
It's really cool.
Adam wants to organize a Houston meetup for Thor.
He loves this project, so he's dying to know the state of Thor.
Yeah, about a year ago, I fell in love with it.
You mentioned it as a hidden gem, though, so that's really important because I've used it for about a year.
I talked to other Rubius, and not many people know about it.
So you mentioned it as a hidden gem, something you want to document.
Where is Thor at right now? What are you doing with it?
Sure.
So Thor was actually originally created because I created the TextMate gem,
which lets you install TextMate things
from the command line.
It will automatically reload and whatever.
And it was a binary that looked a lot like the Git binary.
So it was like TextMate install blah,
TextMate search blah, right?
And that's actually really common.
And I found it at the time
really frustrating to do option parsing and dealing with, you know, shifting things off argv, and I
think that's still how a lot of people do it. And I was like, this is a really easy pattern. In the
same way that, like, Rails is a really easy pattern, there's a controller, there's a bunch of methods,
there are actions, have a nice day. The problem that's being solved is a really easy pattern there's a controller it's a bunch of methods they're actions have a nice day um the problem that's being solved is a really easy pattern
and the pattern is the pattern is is illustrated as there is a class like a rails controller and
every uh sub command like you do like uh bundle install right bundler uses it and the install
command is a method called install and you can can, like with Rake, you can specify
how the command should work. So you can specify what
options are available, what types those options are,
whether they're mandatory, optional,
what their defaults are, things like that.
And it will automatically generate a help command.
So you can say, like, bundle help, and that
output is actually just auto-generated
from
Thor. So that was sort of the initial
motivation, was like, it's really hard to write command line tools
that behave like this, like Git.
And I wish it was easier.
Since then, though, it's been used by a lot of projects
like the Engine Yard Gem, Rails Generators
use it as the base.
The Bundler uses it.
So it's been used by a lot of these fairly large projects with advanced CLIs,
which added a lot of features.
So Thor itself got a lot of features just because people were using it to build advanced CLIs
and they were running into issues.
So Thor can do a lot of stuff.
But we added these features mainly because, like, Engineer was like,
hey, we want subcommands.
So we, like, sort of added subcommands.
Or, hey, we want, you know, we want health to be more easily overridable,
or we want colors, right?
So all these features got added.
When we did the Rails generators,
we want some ways to do file manipulation
and sort of normal generation tasks.
So we added those features.
And so there's all these features in Thor
that are sort of documented in the readme,
but there's no real sort of big picture
story, like, here's how Thor works, here's what
Thor is for. And even though
it has a ton of features that
make it really easy to just crank out a CLI.
So, and we also have been
talking about it wrong. Thor,
the quick pitch for Thor is
Thor is a framework for building CLIs.
It's a toolkit for building CLIs.
And if you have a CLI to build,
even if it's really simple, it's a good idea.
If it's really complex, it's a good idea too.
And I'm like,
I really, I've heard this
from a bunch of people recently.
Like, so I
either, I really love Thor, or
so I was thinking about building a CLI, and I looked
at Thor, and it looked really complicated. I don't really know how to use it.
And so I want to take the time to show that there's like a really simple way of using it.
And then there's really advanced, powerful features for doing anything that you might want.
Like here's an example.
You can like there's shell.ask in it.
So you can like essentially like Highlines ask, right?
You can say like ask the user for input and get a value back, right?
So that's not particularly hard,
but it's, like, another thing you don't have to think about doing,
which is, like, common when you're building CLI.
So if you spend a lot of time on GitHub like Adam and I do,
you see two types of projects over and over again,
.files and ThorTasks.
Seems like everybody's got their own batch of ThorTasks in their GitHub profile.
Yeah, so Thor was also built as, like like a rake replacement plus a sake replacement so sake
is something that um chris monstrath wrote a long time ago that let you install rake tasks into your
system and i thought that was pretty cool at the time so i made it possible to install a thor file
from a remote system or from your system into the global space basically and, and then you can run, like, Thor minus capital T,
and it will give you a list of the namespaces
that are available in your system.
And I think there are some number of people out there
who have taken to that.
So obviously that won't work if you have a bunch of files
that are all distributed in a bundle, right,
which is common for CLI.
But if you're building, you know, a simple script,
like a friend of mine recently built a script
that lets you go into any directory
and ask for the most recent
10 commits, pick two of them and it will give you
will open the diff of those commits in TextMate
so that's a pretty self-contained script
and that's something that
makes sense to sort of stick on a gist
and let people say Thor install
that gist and then use it
That's actually how we do our post to the changelog.
We can have a Thor script,
or you can just pass it to GitHub repo,
and it pulls down the metadata and pre-populates a template.
It's pretty nifty.
That's awesome.
Well, thanks for joining us.
You're a hard man to catch up with.
I'm glad we finally got you nailed down
and had a chance to chat.
Yep, thank you very much.
It was great being here. Thank you. So how could I forget when I found myself for the first time
Safe in your arms
As the dark passion shines