 Trying to prepare So this is on a gym installer, which is a app I wrote This is me. I work for pivotal. It's one of the sponsors and gym installer sort of goes against some of the conventional wisdom and in rails and or Ruby I said don't underestimate the power of versions and vendor nothing You should have explicit dependencies and versions Yeah, try not to play fast and loose gym installer is really comes down to yaml file If any of you have ever used a maven and Java kind of the same concept specify everything and it automatically just as everywhere It needs to be looks like this So it's really all about discipline. I'm sure these screens will be sized wrong to you So this is a gym installer home page I've got some time writing some nice documentation stuff But basically automatically install all the correct versions of whatever you need wherever your app runs Across multiple applications machines platforms environments and also make sure that all of those versions you specify around your load path by the Either the old required gym or gym command Automatically reinstall missing ones, which is now built into Ruby gyms And even if you really discipline print out All the gyms that you don't have specified that somebody is that perhaps installed on your demo server to make it work but not on your production avoids this syndrome here and Try to practice what I preach. I started gym installer about 08 11 and I've maintained backwards compatibility with all of these versions as a Ruby gyms has evolved and As you can see they released 110 this morning which broke me which is really funny because yesterday I was green against truck. So go figure. I'll get on that Code coverage and stuff try to be good All the red you see is that versions of Jim Ruby gyms, which I didn't run for this archive sweet and I don't know how to consolidate them and One really really cool thing that I'm extremely excited about that just made it into rails two days ago It's not vendor everything and it's not Jim plug-ins. It lets gyms be plug-ins and You can see David Hattermeyer Hansen himself committed that a couple days ago It's the same one who said don't overestimate the power versions and the really important thing of this is This right here any gym that you load prior to your rails app starting you can detect by looking at the loaded specs and This patch here will put a hook in to rails Like in it rails and if your gym has an in it rails method then All the stuff that's in that gym in its specification to be on the load path is going to be on your rails Load path, so your gym can be a plug-in if you have that hook It's gonna be really cool so Discipline at that pivotal is probably we have 50 60 plus rails developers We are very agile shop We have lots of projects lots of customers usually get project from nothing to out the door in just a few months When you pair programming we switch pairs which projects frequently we switch pair stations frequently We really re-image our machines frequently we Deployed a lot of heterogeneous environments for different customers we run everything on CI we We have lots of common plugins both internal libraries and we have plugins which provide application functionality Which we sell and license to our customers so in that environment You need to have more discipline than just a couple of guys hacking rails apps nothing against that But it's just a different environment and if you don't have discipline You should have bad guys come after you scary guys guys like you know TDD BBD whoops got my slides out of order. This is what you want to do. Should do this But we've all seen that guy. He's he's kind of scary, but we've seen him a lot, you know That guy's a little bit more scary, huh? That guy's that kind of kind of scary But uh, you know if you're the kind of developer that Will install a plug-in it has dependency manually install that gym on your workstation Just fist that up in the CI and all your other Developers on your team, huh? Can I can I get As for permission rather than forgiveness Okay, just a few more That that's the guy that you really don't want your team don't he's not there and You deploy the demo, you know, that's the guy I really don't want on your team scary guys, so code Now fuha this is how it works One flat argument against gyms is you don't want to depend on Ruby for do you know how to do that? Here's some gyms that I Have on my server. Here's a local gym server and When gym installer Right everything's installed so I'm gonna install mongrel Which is a native gym Run it again, it's gonna automatically install that for me. So that's cool What's cooler is Over here the It's a hook. Here's how it hooks in the rails. It's pre initializer hook boot.rb This is a patch. I got into rails this runs before rails initializes. So there's the two steps There's installing your gyms and I'll gym, which is putting them on the load path and So then when you run your rails app, it's gonna make sure everything's already installed and Here's sample rails app. This is included as a fixture in In gym installer itself this showing all the stuff that's gone in the load path How many of you vendor your rails to have different versions? Well, like like I said with our plugins and lots of different projects We want to make sure that stuff works against multiple rails versions so we can do You saw right here. I'm running rails 202, which is the default latest one in my gym I'm gonna export this environment variable Whoops, restart my server Come back over here Well, I'm automatically running 1.9. I know and like I showed over here On my CI build you can do the same thing You can have your CI building against all of the versions of rails that you need to support for all of your libraries Which has saved our ass a lot of times the Little bit more code the One cool thing it could do is You can include different configs, which I've got here So to stay dry you can have this in a common place shared across your projects And all of these YAML files are parsed through ERB so they You can pretty much do whatever you want in it If it doesn't do what you want write some ERB to do it, and that's how I accomplished the rails version a patch and It works on Windows almost It was working until we regents want to working on that. Anyway, thanks a lot. I'm glad I'm second That's why all the dumb stuff that's in my presentation isn't beaten completely to death yet, but We shall see Okay So I'm gonna show you guys a little thing I did with Twitter plus XMPP which is Jabber for those of you Don't know plus Ruby equals the omg This is a solemn sombrero saga So who am I I'm jade mesquil and the founder of integrum. We do Ruby on rails consulting. There's our site. There's our blog Magical Again here we go Okay, so why why would you want to use? XMPP integration with Twitter Versus their API there the XML API they provide is a is a really really great API But it produces a lot of load on their servers So they limit you to 70 requests per hour, and they actually scale that back when they're under heavy load XMPP allows you to instantly respond to a message that you may get Um saves Twitter money and server load So I'm gonna show you guys just a little bit of code here Hmm I stole most of this from some post I found on the internet by this guy I'll give you the resource at the end. He did a lot of heavy lifting. He built a really nice abstraction Created a Jabber bot that at its core just does very very little Then built a Twitter bot on top of that that integrates with Jabber The one thing that he didn't do that that I really loved is inside of every XMPP message from Jabber is an atom feed That contains a whole bunch of the data of metadata about the message that you received So it's not just the text message itself so what I did is I I pulled that out and I used the Twitter gem and basically emulated the XML API That's this blocker code right here to To be able to pass it off to my Rails app or whatever I want To treat it just the same as if I was using the the regular Twitter API Then what you do is you create a specific Implementation of your Twitter bot and you can do all kinds of callbacks cool stuff I'll have code that you guys can download at the end. So I'm trying to keep this nice and brief This is purely gratuitous sombrero action No sombrero sear. Well, maybe a little one So I stole I mean, I guess forked is the new steel I stole this from this guy And in the room we built a couple of silly rails apps One is Twitter sign if you see a cool sign you can send us a message And it will create these nice little signs One of my favorites is we saw this in Austin. Where are you almost never closed Monday through Friday? More children of death by electrical shock great Another small thing we built is a little app called props You can give your friends or enemies props or drops through Twitter And it will keep track of that you can go to Twitter props comm to check that out And we built the iPhone interface and then a real full-fledged web interface is coming soon Let's see at github I have the actual code that we use for Twitter sign the rails app the jabber integration everything You guys are free to clone it do whatever you want with it should give you a nice little head start If you want to build something similar something similar to overheard or what we're doing Things you must do visit my blog Give me props for being so awesome and give me drops for shameless self-promotion. Thank you Okay, this Well, I'm the catch TV guy. Thanks for sticking around. I'm not explaining catch to be again For those who weren't here catch to be stores the basic The basic storage thing in couch to be is a document and documents can have attachments. Well, I did I can do that. Sorry Okay, I can't seem to what sorry So what what can you do? Sorry? So What I did here I created a simple Application that is just an HTML page. I put that HTML page into a couch to be document attachment For those who can read the URI here I'm on my local machine local installation of couch to be in the demo database and I have this special document Called out and I have the attachment main HTML. This is an actual HTML page And I'm acquiring like couch to be live from the browser here on my local machine show this to you Now this is a very very simple message board. I Can answer new topics here. That's nothing special about it and Other people can also do this when I click on the topic here. I can see my text other people's other mouth folks can reply Might have seen the chicken presentation So this is very very basic application The cool thing about this as I said that runs directly from couch to be when I fill out the form below and submit it a JavaScript Ajax call talks actually to catch me puts the data into couch to be and then reloads the current page which triggers another Ajax call that reads the actual topics and the The threads are the discussion thing here works in the same way This is very unspectacular what I'm going to show now is We have That there's another couch to be server running on the Internet And we get this error message when we call the same URI on this remote server That is because I didn't do replication. That's what I want to show here to how to replicate the the application and the data over Over to another remote server So we go to the couch to be administration interface That's the building in Administration interface is couch to be of the installation I have on my notebook here And there's a replicator thing and I now want to replicate the local demo database to the remote database That lives fuck Let's see Yeah What now happens is the the application the document with the application in it and all the the files that built built the application as well as the Discussion I just put in will be replicated to the to the remote server Or it takes us a minute or second or two depending on how fast the Internet is. I hope that works That's probably slow Sorry for the delay here In the meantime, I can paste the URI that you'll be able to access the remote server as well It seems my safari just went away. Okay, that's kind of bummer. I'm gonna try again. I'm very sorry about that So could you can you guys open the the URI I just posted on IRC Do you get something there? Okay, try again Okay That's that's just too bad that the internet doesn't work at the moment. Oh, it does. It's just very slow Okay, the replication apparently did work we just need to wait another second here What happened is that I have no remote database server that the couch to be server that Just got the application including all the data for the application from my notebook replicate to the other machine and I might have given you the wrong URI Try yeah, sorry How do I get here? Sorry You Okay, everyone who's on IRC now gets another URI that's actually actually pointing to this application No, you can use this application. Please add some comments there What would like to what like you to invite to do that? Sorry Kind of mess here. So if I disagree I say what if I got a new new topic foo, blah I Send this to the remote so it will take again a bit. Okay. This is shoddy with the internet. I'm sorry I should should have been better. Okay. This is totally a non-success here Kind of balancing what I what I plan to show is that what is what is it possible here? Is we have now this application that would lift only on my machine with the discussion board now lives on a different machine where other people can use it and one They these people on other people can get the replication Well when the discussion that happened on the other machine can now can then be replicated back to my machine And I would be able to engage in into the discussion even if I'm offline or which I'm apparently at the moment So That should have been a cool demonstration of how to do distributed applications running on couch to be you don't have to do the JavaScript thing like I do you couldn't can do a Ruby application in between Or whatever you want to have in between The idea is that there's no central database server that serves all the request But all the people who use the application are the actual actual Notes, it's more of a peer-to-peer application thing and everyone who wants to engage in this application can then Replicate from and to all the peers to build eventually all the discussion that is going on. I'm very sorry that didn't work with the With the internet here. Okay. Thanks. So I'm not going to try any further Okay, sorry Okay, so Yesterday morning. We were talking about ask yard animation on the back channel and I tossed out something I'd done in a golfing Ruby golfing tournament a couple of years ago. So hopefully this isn't too much for anybody Jim why Rick asked if this was an noun or a verb. Yes Okay, so we're going to look at one line of code in something under five minutes. Do we really want to do this? Is it worth this? Yeah Whoo-hoo almost read it up there in the corner Okay, caveat first simple is better than magic. Don't try to be clever Ruby golf is a really bad idea And as Zen spider said when he saw the code that's evil Starts out innocuously enough, right? We are going to set up a loop We'll set up a counter and then we'll start printing lines We're gonna start out by the first thing we're gonna print is clearing the screen then going back up to the upper left and printing 11 spaces with a underline at the end We'll print eight more spaces and then the the body of the duck remember Not much it actually gets worse if I try to make it bigger so And then we're going to go ahead and quack and here's where the counter comes in right? We're gonna check to see whether we're even or odd and then we're either going to print a closed beak or a quack And an open beak Then we're going to hit a new line in another ten spaces And the bottom of the duck, but we're gonna proceed that in those ten spaces again, I Guess real quickly Checking to see Whether we're even or odd and then creating the waves so and then we're going to What does sleep sleep one return? Returns one So I plus equal sleep one you get the count and you get to an increment your counter. It's awesome Don't try this at home. Really don't So who's familiar with Coco can we raise hands? Okay, good number and who's running os 10 Macintosh laptops or desktop at home? Good deal So Coco is for those that don't know it's Apple's framework written in Objective-C To do the display stuff and to access various resources Image kit so you can take a picture yourself with the camera help me out Okay, and It just covers a broad range. So one thing that I have been doing is using EC2 for my staging environment I booted up and I do some stuff for a couple hours and I shut it down for weeks at a time until I need it again And I've been unhappy with the Firefox EC2 manager thing So one thing I started last night was a Ruby Cocoa app So Ruby Cocoa is if it's not obvious it lets you talk to Cocoa through Ruby It's something Apple has adopted in leopard. So if you've got Xcode, which I imagine almost everyone here does That is running OS 10 Then you have access to Ruby Cocoa. So we're going to try and do a first iteration of a EC2 manager in Ruby Cocoa in As fast as I can So we'll create a new project and the first thing we'll do is Lay out the interface and this is gorgeous There we go. Nope. Okay, so the two things we'll need are two text fields for our Amazon web services Key and secret Button to bonk on to make it go and do its thing we could just check to see if they're both filled in and whatnot but we'll do the button and Sorry a table view to show the results I don't recommend this UI, but You know, we do what we do with the time we have So the first thing we need now that the UI is laid out Is a controller to run everything So we're going to go in and they've got a nice little Ruby NS window controller subclass We're just going to call it EC2 mugger controller And it goes and creates that and I'm going to cheat I've got text clippings for the things I need That have been scattered about But the first thing we need is obviously to require Ruby gems and we're going to use the right adw s gem that Jonathan talked about before And then that next thing we need to do is we need to be able to access The two fields so that we can pump them in to write adw s and the text area so the way you do that in Cocoa is you set up an outlet and the way you do that in Ruby Cocoa as you tell your Controller I be outlet and then you give it a name and then with that we can go back to interface builder and We need to create an instance of our controller So this is a lot of hand-waving. There's a Good book on Cocoa that I actually would recommend But Aaron Hilligas, but now that we have that we need to go and tell it that it's Supposed to be an EC2 mugger. We draw some lines here Tell it. This is our access ID This is our secret key and then this guy is our instance table view and then now We have instance variables within this class to access those things We now need the action to go ahead and talk to write adw s to load it in So we just pass in our access ID our secret key and then we call this Sorry Describe images by owner just by self since we don't want too much And then we tell it this is an ID action interface builder action So now when I save that and go back to interface builder, I can drag the other way going from the button to the controller and telling it to line that up with the That load instance action that we just dragged in there so then I Don't know what number on fourth Maybe we need to tell the table view that our controller is also a its data source And that's also just a cocoa deal So now it's going to ask the instance of the controller, you know, what's Okay, thanks It's going to ask for these two default methods. So we're going to Basically implementing this interface for a number of rows and table view And we're going to say instances that size and I don't know that rescue is there for fun and Then this table view under object value. These names are hideous because of the way the bridging is working Anyone who's done objective C knows you do the funky brackets and you pass colons and everything's named and it's actually quite nice once you Get used to it, but this is how they decided to do translate the The two things so now we Are what wired up as our data source we have implemented things and the one thing that I'm doing here is um In instances, I'm calling the row and then I'm using this column that's passed in over here I'm using its identifier as a symbol to access that so we actually have to go fill that in So we need to tell this Not that The table column this is going to be AWS ID and this is just part of the Right scale stuff and this is going to be AWS location And I think if I'm at all lucky I can drag in my ID My secret and this is little snitch telling me it's actually going out to ec2 and it loaded those instances So the next step would be able to start one stop them You know all that stuff that it doesn't do but that's it. Thanks So I will Have to make the confession here. I am definitely guilty of Being a polyglot. I love Ruby, but I Sometimes live the second life of being a IO hacker So polyglot means a person who knows or is able to use several languages and so what is IO? Well, I'm not talking about input output Not talking about the moon orbiting around Jupiter or this I'm talking about a programming language So here is hello world in IO you take a string and I'm telling it to print itself out Here's something a little more involved. It's basically, you know the 99 bottles of beer on the wall This I'm trying to show the more familiar aspects of the language. You've got your shebang at the top You've got a you know function That has a couple ifs in there and you know a return And then you've got some sort of a for loop kind of figure out what it's doing and some rights there But yeah IO is objects though and I want to show that more so because you know well idiomatic IO code really Takes advantage of this. So here's another example We build an account and we have a balance and deposit I really don't want to go into depth and explaining this would take too long But there are a couple interesting things to to note about this first of all There are no classes in IO It's all just objects now. Yes in Ruby classes are objects themselves, but it literally is just objects Implementing an entire Object protocol and object system So we call these prototypes in IO and prototypes can be inherited So you can take a prototype and say I'm inheriting from this prototype You can change these prototypes on the fly in IO so you can decide one minute that You're a car and another minute that you're an airplane. It's up to you It can be quite absurd sometimes, but sometimes this flexibility is needed So the other thing is there could be multiple prototypes. So you can do some pretty creative things with dispatch There can also be zero prototypes if you want to be some sort of rude object with nothing else backing it There's another cool thing about IO's object model The inheritance between these prototypes is differential and what that means really shortly is that When you take an object your prototype you want to specialize it and You take that and you clone it We can go back up to this and you see I'm taking a generic object and cloning it and making Account set to that with with some custom stuff inside, you know the balance deposit and show stuff But There's one special thing about the differential inheritance what this means is you only store the the Differences between your prototype and yourself not a complete copy and what it means is it's really easy to go back and monkey patch and You know change and update code. It makes for a really really nice Language, you know that leaves everything open that there's there's nothing nothing sacred in IO So can Ruby do this, I guess would be one question what why IO at all and It almost can it's not quite as dynamic in a number of ways, but it's got some cool cool hacks You can do from the Ruby internals talk you might be able to understand some of this code So I'm just creating this class. I'm naming it proto. You could do the whole, you know Class proto semi colon and there but you know, this this is self-explanatory. Anyway, I'm One minute. I'm defining cologne on the on the class proto and you can see how You know, I can I can basically create some sort of a prototype like object system right in Ruby problem is that you still can't have multiple Parent prototypes you can't change them on the fly and other things like that So sometimes that isn't enough in you know with what Ruby gives sometimes you really do need some sort of expressive Environment to you know build a DSL or build a very very specific language for something Here's a quick method That I wrote a few years ago. I'm not going to explain it since it's probably going to take too much time But anyway, this allows at the very bottom the the two lines to work it's basically functions like rubies Injects, but I'm completely doing everything dynamically. I'm deciding What what should be a variable name? What should be a value and what should just be executed like code? Lisp coders will definitely recognize this sort of Setup you can definitely use or code is data and data can be used as code just as easily So it isn't all simple that time all the time you look at this code and you can see you know quite a bit of Well internals you you you're dealing with the AST and stuff But just like in Lisp you can you can build up your language and make this look a lot nicer I just don't have time to show that so IO is really cool because it's also largely written in itself and Some of it isn't written it in itself for performance reasons, you know and see right now, but It's all writable in IO. So there are a lot of things, you know If you wanted to make it inspectable you can go ahead and write it in IO and check out the code at runtime change it Mutated a lot of crazy things So my question is why can't I have both? I really like using a lot of different languages. So IO is one of those and Ruby is another so I Started this project a little while ago called iodine, which is not released yet. It's not quite ready I did some hacking on it the other night, but Not quite finished. There's some major bugs So soon to be released on github, but it implements IO on top of Ruby And soon Rubinius is my goal. However, I started with that goal and They just made too much progress keeping up with their progress was actually the the hard part They they would change enough of the VM often enough that I just decided to wait in and start with just Ruby It's really cool for things like secure code Sandboxing you can really build custom environments You want to run untrusted code? Really really easy for that sort of stuff Really really kick-ass DSL's if you think Ruby's good at DSL's IO is definitely the next step up Very embeddable it's a very lightweight language at the core so you can take what you want You don't have to bring a lot of baggage with it and the concepts are very simple so it's usually easy to implement and easy to Adapt to whatever language you want to bridge it with It's experimenter-friendly So like I mentioned with monkey patching and just being able to attach and look at and reflect on just about any part of the language It's really great for that So right now status. I hope to release some alpha code on github and you know, maybe the next week and Hopefully by go Ruko with a conference driven development schedule I'll do a more official release So here's some further resources you can go to iolanguage.com the official site to read more about IO I've got IOdine.net that I'm going to be setting up soon. It's not really There's nothing really there right now You can go to IO on free node and there are a lot of helpful people. I'm usually there's binary 42 So give me a ring You can check out to the IO repository on github right now I'll be putting my stuff there as well. And if you have questions, you can email me at this address Any questions? No questions So my name is Jeremy Stelzmith from Pivotal Labs, and there's been a lot of talk about Fixtures and how much how painful they are so we're doing some cool things on last couple projects I've been on and I just wanted to share them with you guys Is that big enough? So There's a pattern that they mentioned a couple talks ago Object daddy. I actually know it is object mother And it's just using a factory instead of your tests. It's been around like since 2001 somebody thought works wrote it up and so Some sometimes it makes a lot of sense to specify stuff in your test and just skip fixtures all together One thing that you can do in Ruby is you can actually use DSL's for that DSL's are are really well suited to representing hierarchical data and as you can see Procedural language is really not like if you if you have a procedural style like that's just really painful code right there So this this domain I kind of made up to kind of a mirror very simply My last project that was on And so in this domain, there's a company companies have sites sites have buildings So it's like a city like Los Angeles or San Francisco Buildings have contractors locations. So a much better way to to show this to build it using active record is That DSL. I mean, it's pretty simple I at that if we have time at the end I'll just show you like what the code behind that looks like That took about half an hour to build that DSL and it's it's infinitely more readable. Yeah So if you can do that side of your test, that's actually to me easier and more expressive than a factory You can obviously make that more complicated more keywords. You can put, you know, you can add things like Whatever other fields you have there as you need to but things that are implicit here like who the parent is and it's very Visual and it models the domain much better So that's one thing Sometimes though, like I like to use fixtures my my big gripes with fixtures were that you had to Maintain Yama, which is just painful And that they were global. So one thing we've already talked about was fixtures scenarios So that solves a global problem because you can have different fixtures for for different scenarios and within your test You can for example For example here, you would just say scenario simple company So I conceivably have like multiple scenarios One of them is simple company that just has a couple locations and and then you're not polluting the whole namespace You don't have you change this one scenario or this one fixture and it breaks all your tests because you have multiple small groups of fixtures The other problem with scenarios is that they were in Ruby as I said So there's something called scenario builder that I didn't write somebody else wrote it. I think it's on Google code There you go And it's awesome. Basically it solves that problem completely. So What you do is you you define a scenarios RB file put it in your spec or test fixtures directory and you just Define a scenario and you can define that in active record If you put that together with defining your data in DSL's all of a sudden you have something That's really really powerful and much much easier to maintain Then then just Yama. We were talking about problems with validations not being run All that stuff is just it's taken care of because it's active record One thing that I still do and that you can do with fixture with scenario builders You can still have Manual fixtures so occasionally I might have something that that is actually it's invalid data or something that active record won't get Let me get into a certain state and I can still go all the way to the YAML and actually check those files in But the other YAML is just generated every time every time I change this file so here we see this is the simple site example and I mean, it's it's pretty self-explanatory. Yeah, so there's a simple company that has two built Two sites one building in each site in two locations Here's a more a more complicated example It kind of just makes sense And I definitely don't use this all the time like for example what one good example One common thing that happens is you actually want to do a lot of stuff with the data And you don't want to expect to get exactly certain things back That require a lot of knowledge of what's actually in the fixture or you just want that for like one specific test in those cases I don't bother putting into a scenario I just put it in line and because I have that DSL is really easy to do that so in this case we're trying to have copy pasting of a site from one company to another and So I just go ahead and create my company Just with the stuff that I need for that one test and then over here one thing that another thing that another Pattern that we do a lot of is round-tripping. So this is the that's the ruby to create the active records And the active records know how to create the ruby that you use for them. So basically After I do a paste of of this site a It should look something like this and that's that's like readable by me as a human cool So that's pretty much it if you have any questions or want to know more just go to my blog My blog at one man's walk comm it should be up there like tomorrow the next day or just email me at Jeremy Stelsmith at GMO Thanks, okay punch is a Something we all like to do is track our time Punch is a command line time tracker Written by Aira He's not here. So I'm doing this for him Anyway, it's super lightweight. It's just a single user on your computer It's a punch card style. You punch in you punch out. It's has YAML storage That's super easy syntax and you can gem install punch if you want to use it This is the syntax punch in and your project name You can punch in an hour ago. It uses the chronic gem You can punch clock something you did before so the first first argument is when you started and the second argument Is when you finished so that would that would basically punch in an hour and a half on the project name project You can punch in on a project and give it a task name so you're the dash M is a message So you're talking about punch While you're in a project you can send a log if you're switching to a different task So you basically say punch log the project name and then whatever you want and the quotes are optional so both Two and three there kind of do the same thing Then you can punch out of a project right now or you can punch out 20 minutes ago or whenever you've finished And then this is how you do your reporting punch list will give you a list of all your projects Punch total will give you a total of every project A punch total after yesterday will tell you how much time you spent yesterday or after yesterday, which is today anyway Then you can do after last week and then you can punch list project and it'll list all that all the time records you have All the output in punch is yaml So you can pipe this into something else or you can get it in a some ruby app you can just Run this command into an IO and read it and do whatever you want with it And you can punch list what you did in January by doing after January 1 and before January 30th And then you can punch dump or punch dump a project and that'll give you the raw the raw YAML that this was done as and then the the data is stored in your home directory and dot punch dot YAML You can just edit that file and do whatever you want Okay punches punches written using main main is totally different than punch Main is basically a controller for your Command line apps and it's used actually by a lot of people how many people use main Okay, not as many as I thought okay Anyway, main main basically makes it really easy to to write command line applications And it does a whole bunch of stuff for you. It's an excellent example of a DSL So this is a main app right here You require main and then you have main in a block That's the every main app has a main in a block and then the mode is The first argument after your application So if you if you typed on the command line my app dot rb install it would run the block That's inside mode So that this is this is kind of the bare bones main app Some of the advantages of main is it has the this unification of options arguments keywords and environment It auto auto generates you generates usage and help and validation You the modes can be multiple levels deep so you can say install My thing right now and it would it would you could go into your whole block block inside block inside block till you Got to the thing you actually wanted to do has I'd IO redirection logging has error handling and exit codes and You can use your own DSL. There's no namespace collisions of anything and it parses argv and all that stuff Okay, don't I get ten minutes since I'm doing two things Okay, let me go really fast here. So anyway, these are the arguments you can pass in I'm gonna flip through these You can read these online after actually just go to code for people calm and Ruby live and you can read the read me for all these things These are all the options you can pass an option and So this is a little bit more involved one You basically have the main block and then you say what arguments you you're gonna have the arguments come in ordered In on the command line you have keywords you have an options and you have the environment and This app basically would output this so these line up with each other. So if I ran this command line This is the output it would it would do and then This is help So basically if you type your app dot dash dash help or dash H It automatically outputs this based on the code on the left on the left here So all that stuff is done for you And this is some advanced stuff where you can have mix-ins into your main. So if you have common Arguments or keywords that are used on multiple modes. You can mix them in so you only define them once and then you mix them into your Into your mode that you're currently in That's it. Thanks. Thank you Okay, so one of the really awesome things about working in j ruby is that you can bundle all of your ruby code into a jar and What that means is Nobody actually really knows that you're working with j ruby It's all just Java and so you can leverage all the things that come with Java J ruby is just a library that happens your package with it. So you can Just double click your jar there and after a few seconds, it'll pop up your app Even though the app is almost completely driven by You know ruby code how that applies to Java web start is that I Can give somebody a link and it just downloads and runs the app. I already have it downloaded because It's about a six meg download So there's my application now. I can make a change Change our red text to blue to green Save it there That's the wrong one I have to sign the jars and then I can transfer that over to My main server here Wow, this is annoying And so on my server Now when I run it again It automatically grabs the latest version and starts up the app Now the text should appear as green So you've got auto updating Java web start will also install desktop shortcuts and Among other things That's really all I have to show Do I have time for questions Any questions? It's a weird security thing with Java. You have to sign your jars in order for them to be trusted I'm using kind of a temporary developer signing right now So that's why it comes up and says this is untrusted. Do you shoot like this? Hey, I believe you have to go through very sign actually pay them somebody to sign the jars for real Anybody else? So long as you have java installed Yeah This this is the remake making using monkey bars, which was the like and talk we had yesterday Is that the Yeah jvb complete is about five megs the jar for that and that comes with the core lid but you could Probably truncate that down by pulling out a lot of that stuff that you know Thank you. Okay. So this is our rails helper. We use to save us a lot of time They're autosaving fields. So they're their um input elements on on a web page that know What data they contain so they know what object what column what table So um you say like autosave user name says, okay. Well, that's that's a field And so you get this this autosaving field I know whatever and then you know, so it's saved. So when you reload the page you get the new value You know say as select you get select you pass in some options that tries to be as smart as possible So if you pass in active record objects Well, let's get into that later. But you know if you pass in like user prefixes is an array of string And it knows okay You're storing the index in the database and it gets the the text from what you're passing in As check you get a checkbox So um, but they're kind of ugly. So there's a pretty simple skinning system You can create different appearances. So this is you know, you click on it and you you type in something I'm stuck in gibberish You know, this is a this is the checkbox a different appearance for the checkbox goes is not this is a different appearance for the select box You just get the options here and you know chooses whatever and You know, you go back to the thing you can see that it saves Here's another simple appearance. You know, this is more like the you know edit in place It's got a save and cancel button Okay, so What else it's got hook backs so um if you Give some java scripts to call when you're successful. It'll call that um, you know, this got a simple validation. So if um The save's not successful. It calls a different java script. Oh Actually, that's good up. So to do the different skins. You just you just pass in the name of the skins And uh, it looks in a directory for them Again edit button skin hook backs its java script is a successful one failures the failure one Okay, so next uh associations Um, it's got one-to-one associations So whatever, um If we look at what that looks like again, it's just the object and the in the um association It asks rails. Okay. What kind of association? Oh, it's one-to-one. So we'll show a select box. Okay It's type company. So let's get all the companies If you don't want all the companies you can either pass in Just the array of the companies you want or conditions clause and it'll just cut the ones matching the companies matching the conditions clause Um, so again, both of these are just the ones starting with s Trying to get something lower on the page And I just okay. Well, let's let's see Oh, I'm just gonna I can't seem to scroll so I'm just gonna Get rid of the ones on the top of the page One-to-many association. It gives you a whole bunch of checkboxes again. They're they're all out of saving Um, it saves time because you don't have to implement any of the back end You know, it knows It all goes through a single method that that comes with the stuff. Uh, you have to implement any of it um, it's all sort of there and then last is file upload it's got a non page reloading file upload um Oh, let's do a simple So didn't reload the page it updates the image For that you can pass in um after And give it a function and that's the function we'll call after um in the case that you've got in case you have a bunch of uh rjs, um calls you want to make through different afters Gives you also render and it just it takes the block and just when it goes to render just pass all of them So you don't have to worry about double rendering And that's that's about it so That's me. I'm Jim Linley. Um, I work for academic management systems. Um We do software for universities The problem we have is an app. Uh, it's currently in visual of fox pro But we're converting it to rails because visual of fox pro is discontinued. Um, it's a Some of the things we deal with are uh surveys and questionnaires where each level at a university gets to add their own questions So, uh, um the typical design of a form is problematic. Um We can have up to 1,000 slightly different forms. Um per install Which is uh pretty hairy um So The issue i'm trying to solve is that we have to uh, heuristically generate some form layouts Um, and I wasn't sure where to start. So I went back to basics and uh, here's a rail scaffold And it generates this sort of markup, which is fine. It gets the job done But to get to where we need to go is uh, uh the form builder comes up and uh, how many people here have made form builders before? Probably lots of you. Um it's uh, um, basically just subclass the rails form builder and uh add your wrapping markup So you can get rid of some of those p's and b's Um, it's pretty old news has been in rails since I think uh 1992 um All right, uh accessible form builder is a plug and I started with. Um, it allows you to add notes required asterix labels Um, the markup looks like this. Uh, you can see a few lines down. Uh required true Few lines after that note be festive Um generates all this markup. Uh, there's not much html here. I think just the h1 at the top Um, this is all pretty basic rail stuff. Uh, and it adds that required asterix for age and the note at the end of headwear Um All right, uh, so here's where I took it. Uh from the existing plug-in Um blueprint is a css framework. Has anyone ever used it? fair amount of people um It uh, basically strips down all of the browser's default styles builds it up and gives you a little bit more Column layout typography default styles Um, this form builder needs reset and grid files to work um In uh the form builder And for like a text field you would add a couple extra parameters. It would generate group Blueprint css classes Um, so here is a a different example And you can see um like the top line span six that tells blueprint. Uh css to apply Six columns to it. Um, and there's a slight shim to grid to blueprint css to help make some of this work um So here's the layout um from uh, this is this no real html and the css is just from blueprint and the plug-in Um, you can get columns and a few other niceties Um, and the reason we need this is that uh with all these different forms We basically have to serialize the form layout. So we take the All the different options hashes And dump it in the database and then uh when the user comes you can generate the form from that um So a nice decent looking form without too much work um And additionally all the the existing rails form helpers are uh alias to uh with bear so that if you ever need to drop Down you can do that And uh if you need a quick forms prototyping that's sort of a thing. Uh, you might find this useful um I'm gonna add some specs to the plug-in that were nonexisting Continue to add css to uh make it more useful to people And then um, eventually I will release the uh corresponding plug-in that serializes the form layouts And then um, I'm hoping to create a flash reflex gooey for editing forms And generating code So I still work in progress and here's some credits for the Um really good work i'm building off of I don't know if either of those two gentlemen are here But uh if you are thank you And uh, that's it. It's on github and uh, thank you very much My name is pj. Hi, it's and i'm one of the github guys along with christ swan stroth and tom Preston warner That was actually a beautiful segue the Previous lightning talk had a project on github Uh, as soon as I figure out this display Oops Not cool All right, so Well as I'm I'm sure most of you know what github is because of the fact that Half of the talks I've heard included their link to the github project Um, but for those that aren't familiar with it github is A place to store your code using git Which is an infinitely better source control management system than subversion or cvs or Anything that isn't distributed basically we can talk later if mccurials just as good or not, but um So basically if And I'll give you the email at the end of my talk So if you want an invite and you don't have one feel free to email me But this is this is what you'll see When you first get to github and I'm just going to do this locally in case the network gets flaky, but You'll come to github and you'll say well There's this really awesome project that I want to work on I mean github does host private code But one of the awesome features is how well it does open source And what we're doing is we're not We're making git Even more awesome than it already is by exposing these things via the web interface So as instead of the the way you would do it with subversion where you patch things and I'm sure all of you Know that patches can be extremely problematic and just A general pain in the ass So git simplifies that and I will show you how So there's this really awesome library that we're using on github called grit. It's something tom's been working on It's a ruby interface for git a ruby wrapper rather and so I would like to fork that and One of the previous talks said fork is another word for steel, you know call it what you want, but It's as simple as clicking fork and memcache is down That's what I do good for doing this locally Let me just restart this I guess I could just use the real website Let me try that one more time No, okay. Well, let's use the actual website And see what happens. I'm sorry I've got my I've though Uh All right, so we're really We're uh, let's see how many things can go wrong for this All right, so I'm going to do the exact same thing only on the real website. This is tom's grit application And I'm going to fork it so I just click fork and Doing some hardcore forking action I uh I'm now going to have my own copy of grit And this really depends on whether The network is going to There we go So here's my own copy and the beautiful thing is is that now if I want to make changes to grit I I use this url. I I clone it and pull it in Do my changes and go Go back to Tom's original Tom's original grit library and go And go and go where is The poll request Do I not even know how to use my own website? That is the question Um Apparently not Oh, it's That's yeah, that's why um So let me just pull up one of my own repos so I can tell you how this is actually supposed to work Um, that's for later So let's say this is this is one of my project auto migrations Um There we there we go Auto migrations. So let's assume that I've actually cloned this and it's not my own project. I go I click pull request and I go Hey, dude Just made Some incredible changes Check it out and I don't know why I would add myself, but Actually, this is Strange there's I don't think the Ajax is working properly But let's assume that I send this poll request. Maybe maybe this will work But um Essentially what it's doing is it'll say Hey, Tom. I I just made this awesome change set Pull in my repository that I forked from you And instead of dealing with this whole patching, you know scenario that can be so problematic one of the things that git does very well is Merge and so what he would do is he would pull in my my clone Into a remote branch and he would just Merge my branch with his branch and then It's all taken care of So there is it's it's essentially what you would do For everything is that you merge as opposed to patch And that is one thing git does very well So the idea is that instead of giving people commit access They just have to like you enough to merge your branch in so As you know, if you if you wanted to Uh work on some rails patches that involve You know some some major changes you don't have to ask them to make a special branch for you You just clone it yourself or fork it rather you fork it you do all your work and then People are like hey, this fork is actually really awesome and they go all right. Well, we'll just merge it in So I think it's incredibly powerful for how it I think it's it's definitely an evolution for the open source community on on the flexibility and and how easy it is to To get a copy of your pro get a copy of another project do all your awesome changes and then tell them that You know, they should think about merging it So I'm probably preaching to the choir because I know like I said half of you are already using it, but for those that aren't Please Email me at pj at logical awesome, and I'm happy to give you an invite, but that was Probably the worst demo I could have possibly have given you guys But there we go All right, I'm going to show off sequel real quick sequel is a ruby library that let to access databases easily Um, just dive into some code. So you basically require ruby gems require a sequel Um, there's a couple ways of connecting to different databases. You can give it a uri So that's how you would connect to a mysql database. Give it a user pass host db name whatever um You can also Pass in a hash with different options instead of uri. So you could connect to postgres like that Uh, you can connect a skill light. Just give it a file name Or uh for this demo, I'm just going to do if you don't give the sql light a file name It's just going to create a database in memory Um, so we have this db object That has a database connection. We attach a logger to it. Um You could use the standard lib logger like this just Basically assigned the logger Um, so here we're going to create a simple table has three fields Um, this uses method missing to basically pass on whatever string down to the database So whatever your database supports you can use in your schema So at its core, uh sequel is basically Has this concept of a data set which lets you build sql using ruby. So uh, the the simplest data set is basically you take your database connection and Say you're accessing numbers. So this means you're basically doing a select all from The numbers table which we just created up here. So if I run this you can see um Basically the sql generated by that second command is select star from numbers so Uh, we'll go ahead and populate this with some A couple rows run it again. You can see it's inserting a bunch of data Um, you can see in here. I'm using time dot now and and days ago And it knows to convert that into whatever your database wants Um We can go ahead and start querying the database. So When you do a dot print it basically does a nice little ascii graph Uh, you can see it's doing a select star for numbers Uh, you can start applying Filters to your data set and this uses parse tree is kind of like ambition So you can basically pass in ruby code in a block and it will convert that to sql So over here we're doing we're taking this base data set and calling where on it and we say Uh anything in your block that's a symbol is considered a field in your database So we're saying look up basically all rows where the num field Is uh in this range and it's smart enough to know that A range converts to an inquiry in sql And you can change chain data sets So we're signing it to this variable over here and then we chain And we add another clause which is an order clause And then we print it out so you can see Um, it builds this query it knows how to deal with that range And we're printing out those values from the table Same thing we're going to apply a different order clause and now it's ordering by alphabetically by the name Um We can call delete on any data set and we'll just delete those and so Here you can see same thing. It's calling delete on Um using the filter we specified and you can see those rows are now gone Um, you can do the same thing with Time objects in here. So again, it knows how to convert that Into the proper sql prints out the correct rows Um, same thing with ranges with time objects So um A couple more examples. I took this zip database from zips on source forage Same thing. I'm connecting to sql database on disk Uh, you can see in here again in this block I'm saying if the state is in this array and again knows to do an inquiry There's a lot of nice methods like group and count Which will do the grouping and the counting I want to reverse them and show the top five cities So you can see the top five cities. The first one's blank. So we can go ahead and add another Where city so, um, there's two ways of doing these queries. You can do chaining Where you're basically chaining on your data set or you can do a query block Which basically you give it a block and then it looks a lot like sql And so this thing is a data set and now i'm calling dot print on that data set so Same thing. These are the top cities in the country And um, there's also models that are built on top of Um these data sets so basically you can define a model and say this model is tied to this data set So i'm giving this data set basically that takes the zips zip codes and pulls out all the states and Makes a model out of it. So I can print 10 of the states and You know it prints out 10 of the states So you can uh find out more about sql There's a Google code project Um, it has a bunch of wiki pages with a lot of documentation. There's also our docs on the ruby ford site There's a cheat sheet wiki with a lot of useful information on here. There's a great google group The the latest release sql one three also has support for associations active record style uh, and there's also a Uh rc channel sql on free node. So check it out. It's awesome okay, so I everybody seems to have their own way of doing um Their own migrations plugins for active record because nobody seems to like the defaults very much because they usually have a lot of problems with Working on we're working on teams. You just run into issues I've seen some cool ones out there like auto migrations and ones that deal with timestamps and all this other stuff This is just my spin on things Essentially the way I look at things is from a database point of view Your database does not evolve linearly in general your database evolves as a series or As a set of a distinct Modules so you may have the base core system of your application as one module You may have permissionings as a separate module And related tables to that for like our back schemas or whatnot You may also have a set of tables dealing with uh addresses and contacts and all that other stuff And of course users and whatnot so What I did is I have the active record um migration branches And I can't see a thing on this thing so and With the plugin if you do script generate see Oh god, this is awful Migration branches it'll come in it'll give you information on the migration branches and anyways How it's used is you do script generate migration branches And you pass it the migration name followed by the branch name And what you're not seeing here is You can pass it any number. Well, this is the current api. I'm likely to change it But you can pass it any number of migration names followed by branch names And it just creates the migrations for in each branch So a couple quick examples to create sessions in a system You might do script generate migration branches sessions system So if I do that So if I do that what it's going to do is it's going to create db migrate system directory because it wasn't there already And then it's going to create uh zero zero one create sessions within this. So basically it's namespacing your migrations for active record So you could do like roles and permissions All as maybe part of your system or whatever and it's just going to go and create these migrations in the system branch And so you see that it's just like having normal active record migrations, but now your name's based in the branch You can create two migrations in say a user's branch at the same time by saying users users and user preferences in the user's branch and it creates them Um also you can create two different migrations within Different branches even during in the same command currently So I created a states table in the lookup. I created addresses and address types in the addresses namespace or migrations branch so That's all neat, but and this is an actual application that I've been kind of playing with If I look in the db migrate directory, we see we have uh addresses lookup tables RWS is actually the application specific tables billing system our back for the uh roles and rights and stuff And a systems table So in let me make sure our database is empty first Okay So if I migrate on this what I see is It didn't do anything Because in the db migrate directory there are no migrations. So by default it migrates along the standard rails migration path Um Okay, so now If you want to migrate a certain branch all you do is rake db migrate branches equals branch name so I did that up there with the um branches equal system And what it did is it created I have a migration in there called fast sessions and that migrated that so it that's one branch you couldn't specify multiple branches by comma separating them So if I want to migrate along the lookup in our back branches, I just look up commis our back and what you'll see is that This is awful Which you'll see is that it migrated db migrate lookup there first. So I've got some lookup tables services statuses periods positions etc And then it also Went to the our back and it created some our back base tables for this application And there's also of course, uh, you can migrate all branches by doing rake db migrate branches all equals all And there's quite a few of them actually So it just goes through all of those sub directories and in alphabetical order currently And we'll migrate them Um, so what this allows you to do is you can separate system out into logical components new feature What this is kind of cool for is new feature development can be kept separate And once the new feature is ready and you're sure those migrations are good you can Um merge them in with the main migrations for the application Or you can keep them separate and label the branch name based on that feature and once they're good, they're good Each developer could have his own branch to play around with the migrations and stuff so that he can see what he is affecting with his migrations and when so he's proved that his migration does its task he can merge it in with the The appropriate branch or the mainstream branch and of course, whatever else you can think of I put it up on github It's github.com slash wane e segwin You can hit me up on irc under that nick as well slash ar underscore migration underscore branches Um patches are most definitely welcome. Uh, this is basically evolved to the point where I need it And I'd be happy to add good functionality to it. So any questions? Nope, cool. Let's get out here I've been challenged to do this in 60 seconds once I have my screen up. So we'll see if I can Uh, first of all, where can I plug in my screen? Uh, it looks like uh, just a regular vga out. There we go Uh, okay, it doesn't look like it's up yet. Sorry Hopefully this won't mess with the windows that I already have open Is it there? No Dang it. I knew this would happen. I'll just talk real quick then Uh, what I was going to present on and what I will still present on though you can't see it is uh granular testing in rails How many of you have gone and run your rails rake test and had it take two five minutes to run? How many of you are add like me? Do you wait two to five minutes or do you go read a blog post? What I've written is just a small rake test that you put in your lib tasks directory that will let you run specific unit tests specific uh functional tests like rake test units and then model name and it'll run just the test for that model. Um, it's all it does is it goes through uh globs the directory takes the file names shortens them makes a description creates a rake task and puts it in so you can see it with rake dash t you run it runs that single test and that's all there is to it Uh, I can't show you code if you want it email me jacob at mozi.com and uh I guess that'll be it since I can't show you anything Have good have dinner