• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Feels Like Ruby - Ruby Kaigi 2010
 

Feels Like Ruby - Ruby Kaigi 2010

on

  • 1,742 views

Making JavaScript development suck less.

Making JavaScript development suck less.

Statistics

Views

Total Views
1,742
Views on SlideShare
1,742
Embed Views
0

Actions

Likes
1
Downloads
7
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

CC Attribution License

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Feels Like Ruby - Ruby Kaigi 2010 Feels Like Ruby - Ruby Kaigi 2010 Document Transcript

    • Feels Like Ruby Sarah Mei Pivotal Labs @sarahmei sarah@pivotallabs.com 1すみませんーはじまりましょうか。
    • 皆さん、こんにちは Hi everybody 2みんなさん、こんにち は。
    • メイ サラ 名前は MEI Sarah です。 I’m Sarah Mei. 3なまえ は Mei Sarah です。はじめまして、どうぞう よろしく おねがいします。
    • 日本語がよく話せないですから、 すみません。 I don’t speak Japanese very well, so thanks in advance for your patience. 4にほんご が よく はなせない です から、すみません。
    • http://www.flickr.com/photos/sunrise/4064417/ 5San Franciscoにすんでいます。
    • アメリカ人です。 I’m American. http://www.flickr.com/photos/junewess/3756778580/ 6Americaじんです。
    • RubyとRailsの開発者です。 I’m a Ruby & Rails developer. Image copyright 2006-2010 Yukihiro Matsumoto 7Ruby の かいはつしゃ です。
    • I work at ピヴォタルラブス に勤めています。 8Pivotal Labs に つとめて います。Pivotal Labs は Pivotal Tracker を せいさく して います。でも、ほとんど の Pivotal Labs の しゃいん は コンソルタンット です. 
    • I work at ピヴォタルラブス に勤めています。 ピヴォタルトラッカー 8Pivotal Labs に つとめて います。Pivotal Labs は Pivotal Tracker を せいさく して います。でも、ほとんど の Pivotal Labs の しゃいん は コンソルタンット です. 
    • (この先から英語です。ごめんね) 9じこしょうかい が おわり です から、この さき から 英語 です。ごめん ねえ。。。
    • (この先から英語です。ごめんね) Feels Like Ruby 9じこしょうかい が おわり です から、この さき から 英語 です。ごめん ねえ。。。
    • (この先から英語です。ごめんね) Feels Like Ruby Making JavaScript a Real Language 9じこしょうかい が おわり です から、この さき から 英語 です。ごめん ねえ。。。
    • What I like about Ruby 10I want to set the stage by talking about what I enjoy about Ruby. First and foremost, it’s thelanguage itself. I love the expressiveness and accessibility.But as a working developer, what I appreciate the most is the ability to test-drive everything.Between rspec, test::unit, cucumber, capybara, webrat, shoulda, steak....I can pick the mostappropriate test tools for each project.
    • What I like about Ruby • The language itself. 10I want to set the stage by talking about what I enjoy about Ruby. First and foremost, it’s thelanguage itself. I love the expressiveness and accessibility.But as a working developer, what I appreciate the most is the ability to test-drive everything.Between rspec, test::unit, cucumber, capybara, webrat, shoulda, steak....I can pick the mostappropriate test tools for each project.
    • What I like about Ruby • The language itself. • I can test-drive everything. 10I want to set the stage by talking about what I enjoy about Ruby. First and foremost, it’s thelanguage itself. I love the expressiveness and accessibility.But as a working developer, what I appreciate the most is the ability to test-drive everything.Between rspec, test::unit, cucumber, capybara, webrat, shoulda, steak....I can pick the mostappropriate test tools for each project.
    • What I like about Ruby • The language itself. JavaScript • I can test-drive everything. JavaScript 11So let’s see how these options stack up in JavaScript. The language itself...?
    • What I like about Ruby • The language itself. X JavaScript • I can test-drive everything. JavaScript 12Well, I’m never going to be able to change that. I don’t dislike JavaScript, but Ruby fits mypersonality better. But what about test-driving?
    • What I like about Ruby • The language itself. X JavaScript O • I can test-drive everything. JavaScript 13We should be able to test-drive JavaScript. But until earlier this year, I didn’t. And some of thebest Rails developers I know, who test-drive all their Ruby code, still don’t test-drive theirJavaScript. So the question is...
    • http://www.flickr.com/photos/petereed/496392956 14Why not? Why do we make JavaScript development so painful?I think part of it is a philosophical mismatch in the way Rails treats JavaScript.
    • 15Web applications are fundamentally written in multiple languages. Here’s a very genericrepresentation of a Ruby web application. On the front end, there’s HTML, CSS, andJavascript, and on the back end there is one (or more!) server languages, plus SQL. And ofcourse, normal applications have other front-end languages too, like ActionScript orObjective-J, and other back-end languages interacting with Ruby, and usually additional datastores as well. I can’t remember the last time I worked on an application that had ONLY arelational database for storage.But traditionally, in this setup, programming languages sit here in the middle. Butframeworks try to extend on either side. That’s what Rails does.
    • ActiveRecord Rails 16For example, Rails extends this direction, and abstracts away SQL with ActiveRecord. It’spretty successful with that. Even on really complex applications, I can get away with thegenerated SQL most of the time.
    • erb sass rjs ActiveRecord Rails/gems Rails 17But it also extends the way with erb and rjs to generate HTML and JavaScript. And with othergems, you can generate CSS too. And although this was a good idea with SQL andActiveRecord, and it works decently well with HTML and CSS, RJS is kind of a disaster. I’ll showyou an example in moment.But first I want to point out that this is not a failing of Rails, or of the people who wrote it.This is the nature of Javascript. It might be the one language whose use is evolving evenfaster than Ruby. SQL has an ISO standard and a committee, and if they make any significantchanges, we’ll have five years’ notice. Moreover, the database products that implement SQLhave committees, so as SQL end-users, we’re exceedingly well-insulated from any languagechurn.
    • JavaScript Developers http://www.flickr.com/photos/gem66/387400306 18But Javascript...is the wild west. It’s the frontier. While the language itself is relatively stable,its libraries and usage patterns are changing faster than that of Ruby, or of Rails, or of anyother framework.What does that mean for us as web application developers, as multi-lingual programmers?
    • erb sass rjs ActiveRecord Rails/gems Rails 19It means we need to opt-out, to make an exception, and to handle JavaScript differently.Now, that’s the philosophical reason - now I want to show you the practical reason.
    • 20In Rails 2, using RJS means you have little bits of Javascript all over your code.Here’s an example I adapted from the “complex forms” railscast. This is a to-do list app, inwhich you can create a project with any number of tasks attached. This is the new projectform. It has 3 task textfields, but you can add another one by clicking “Add a task”, and youcan delete one by clicking the “remove” link that’s next to it. Both of these are implementedas simple JavaScript that modified the DOM. For the purposes of this example, we’re going tofocus on the remove link.So let’s look at how that’s implemented.
    • 21This is the partial that is rendered for each task. The important part is the link_to_function,where when we click remove, it calls that little piece of javascript.
    • 22Here’s what the rendered HTML looks like. You’ve got that little bit of inline javascript, whichon its own, is fairly simple. But it’s not really testable.Sure, you could write a selenium test that tests that it actually removes the dom element.However, Selenium is slow. This is one simple interaction - in a typical modern webapplication, there’s likely to be dozens of these on one page, if not hundreds. Testing themall with Selenium would mean you’d have a test suite that never stopped running.Plus, Selenium is an integration test. If all you’re doing is integration tests, you’re doing itwrong. You need both unit tests and integration tests to probe all the behavior of your code.So how can we re-do this in a way that is testable and repeatable?
    • A different approach 231. Forget RJS - it gets in your way once you do anything beyond the very simple.2. Put your JS in classes - of course JS is a prototype-based language instead of aninheritance-based language, but you can still organize your functions into sets. I’ll show youwhat that looks like in a moment.3. Organize your JS by behavior, and by location.4. Test-drive all your JS.
    • A different approach • Forget RJS - write functions 231. Forget RJS - it gets in your way once you do anything beyond the very simple.2. Put your JS in classes - of course JS is a prototype-based language instead of aninheritance-based language, but you can still organize your functions into sets. I’ll show youwhat that looks like in a moment.3. Organize your JS by behavior, and by location.4. Test-drive all your JS.
    • A different approach • Forget RJS - write functions • Put your functions in classes 231. Forget RJS - it gets in your way once you do anything beyond the very simple.2. Put your JS in classes - of course JS is a prototype-based language instead of aninheritance-based language, but you can still organize your functions into sets. I’ll show youwhat that looks like in a moment.3. Organize your JS by behavior, and by location.4. Test-drive all your JS.
    • A different approach • Forget RJS - write functions • Put your functions in classes • Organize classes by behavior and location 231. Forget RJS - it gets in your way once you do anything beyond the very simple.2. Put your JS in classes - of course JS is a prototype-based language instead of aninheritance-based language, but you can still organize your functions into sets. I’ll show youwhat that looks like in a moment.3. Organize your JS by behavior, and by location.4. Test-drive all your JS.
    • A different approach • Forget RJS - write functions • Put your functions in classes • Organize classes by behavior and location • Test-drive your classes. 231. Forget RJS - it gets in your way once you do anything beyond the very simple.2. Put your JS in classes - of course JS is a prototype-based language instead of aninheritance-based language, but you can still organize your functions into sets. I’ll show youwhat that looks like in a moment.3. Organize your JS by behavior, and by location.4. Test-drive all your JS.
    • A different approach Unobtrusive JavaScript • Forget RJS - write functions • Put your functions in classes • Organize classes by behavior and location • Test-drive your classes. 24These first two techniques are collectively known as “unobtrusive JavaScript.” I am happy toreport that Rails 3 is moving to unobtrusive JavaScript. So Rails 3 will help this problem quitea bit, but, as you can see, there is more to do beyond “unobtrusiveizing.” Let’s look at howwe’d do it.
    • 25Here’s our original example, with the remove link. How we could re-implement it? Before, thecode looked like this...
    • 26But we can simplify this now. All we really have here is a link that we want to add a behaviorto.
    • 27So in the erb template, we’ll just make a link with a class on it. No reference to JavaScriptanywhere here. And here is...
    • 28...the HTML it generates. So. If we don’t put our Javascript in the HTML...where should we putit?
    • public/javascripts ! 29In general, I keep my JavaScript files in public/javascripts. So we’ll create a file in public/javascripts called project_form.js
    • project_form.js 30In this file, we create a class called RubyKaigi.ProjectForm, and we put in two functions. Thetwo functions are initialize and remove_task.
    • project_form.js 31In initialize, we add a click event to all links with class .remove-link. When that link is clicked,our other function is called.
    • project_form.js 32That function, remove_task, actually removes the element with class ‘task’ from the DOM.
    • project_form.js 33The last thing that’s important here is the document.ready, which calls initialize, which setsup the click events, once the page is loaded.
    • 34So I’ve created a JavaScript class that encapsulates the behavior of the project form. Once Iimplement the “Add a task” link, that behavior will go in the same class.
    • 35Then it might look something like this, with a new function at the bottom, and some extrainitialization at the top.
    • Organizing by pageWhat if you use the ProjectForm JS onmore than one page? 36
    • Organizing by pageWhat if you use the ProjectForm JS onmore than one page?Move ProjectForm.initialize to a pageclass initializer 36
    • 37
    • project_edit_page.js 38
    • project_new_page.js 39
    • http://www.flickr.com/photos/uwehermann/132244826 40So that’s how you organize your JavaScript so it’s all in one place. But what about testing?
    • Jasmine @jasminebdd 41That’s where Jasmine comes in. Jasmine is Pivotal’s open-source JavaScript testingframework.It lets you do “rspec-style” testing.The philosophy of Jasmine is that JavaScript should be tested with JavaScript. There are gemsout there such as harmony that let you test JavaScript with Ruby, but that just adds anotherlayer of indirection. JavaScript should be a first-class language in web applications.Also, it is not dependent on the DOM, so it can be used to test other types of JavaScript, suchas for WebOS.
    • Jasmine • Open-source JavaScript test framework from Pivotal @jasminebdd 41That’s where Jasmine comes in. Jasmine is Pivotal’s open-source JavaScript testingframework.It lets you do “rspec-style” testing.The philosophy of Jasmine is that JavaScript should be tested with JavaScript. There are gemsout there such as harmony that let you test JavaScript with Ruby, but that just adds anotherlayer of indirection. JavaScript should be a first-class language in web applications.Also, it is not dependent on the DOM, so it can be used to test other types of JavaScript, suchas for WebOS.
    • Jasmine • Open-source JavaScript test framework from Pivotal • BDD in the style of rspec @jasminebdd 41That’s where Jasmine comes in. Jasmine is Pivotal’s open-source JavaScript testingframework.It lets you do “rspec-style” testing.The philosophy of Jasmine is that JavaScript should be tested with JavaScript. There are gemsout there such as harmony that let you test JavaScript with Ruby, but that just adds anotherlayer of indirection. JavaScript should be a first-class language in web applications.Also, it is not dependent on the DOM, so it can be used to test other types of JavaScript, suchas for WebOS.
    • Jasmine • Open-source JavaScript test framework from Pivotal • BDD in the style of rspec • Philosophy: @jasminebdd 41That’s where Jasmine comes in. Jasmine is Pivotal’s open-source JavaScript testingframework.It lets you do “rspec-style” testing.The philosophy of Jasmine is that JavaScript should be tested with JavaScript. There are gemsout there such as harmony that let you test JavaScript with Ruby, but that just adds anotherlayer of indirection. JavaScript should be a first-class language in web applications.Also, it is not dependent on the DOM, so it can be used to test other types of JavaScript, suchas for WebOS.
    • Jasmine • Open-source JavaScript test framework from Pivotal • BDD in the style of rspec • Philosophy: • Test JavaScript with JavaScript @jasminebdd 41That’s where Jasmine comes in. Jasmine is Pivotal’s open-source JavaScript testingframework.It lets you do “rspec-style” testing.The philosophy of Jasmine is that JavaScript should be tested with JavaScript. There are gemsout there such as harmony that let you test JavaScript with Ruby, but that just adds anotherlayer of indirection. JavaScript should be a first-class language in web applications.Also, it is not dependent on the DOM, so it can be used to test other types of JavaScript, suchas for WebOS.
    • Jasmine • Open-source JavaScript test framework from Pivotal • BDD in the style of rspec • Philosophy: • Test JavaScript with JavaScript • No DOM dependency @jasminebdd 41That’s where Jasmine comes in. Jasmine is Pivotal’s open-source JavaScript testingframework.It lets you do “rspec-style” testing.The philosophy of Jasmine is that JavaScript should be tested with JavaScript. There are gemsout there such as harmony that let you test JavaScript with Ruby, but that just adds anotherlayer of indirection. JavaScript should be a first-class language in web applications.Also, it is not dependent on the DOM, so it can be used to test other types of JavaScript, suchas for WebOS.
    • gem install jasmine 42
    • 43When you install jasmine, it comes with a rake task that creates a javascripts directory underspec.
    • 44I create a new file called project_form_spec.js. In this file I describe the behavior of thefunctions in the RubyKaigi.ProjectForm class. Here’s the spec for removeTask.
    • 45It starts with a “describe”, like rspec, and the describe contains an “it” block. Both thedescribe and the it take a string describing the behavior you’re expecting.Jasmine comes with a small set of matchers - here you see expect().toEqual(). You can alsowrite custom matchers, as in rspec.
    • 46It comes with a little server built in, that starts on port 8888 by default, where you can runyour specs in a browser.To re-run them, just reload the page.Jasmine also comes with a continuous integration task that runs the specs in a browser anduses selenium to determine whether they pass or fail. There are plug-ins that run your specsheadlessly.
    • Summary• Respect your JavaScript!• Test-drive 47
    • http://www.flickr.com/photos/zachklein/54389823 48
    • http://www.flickr.com/photos/rappensuncle/248625025 49
    • Questions? 質問がありますか。 @jasminebdd @sarahmei sarah@pivotallabs.com http://www.flickr.com/photos/rappensuncle/248625025 50じゃ、これは いじょう です。