 My name is Nicholas Schluter as it says up there. I blog at SimpleTree. I work at Ride Charge. I'm a software engineer there. I've been enjoying Rush, the Ruby shell lately, so I thought I'd kind of share some of my experiences with you. First of all, it's not... It's not the band. That's what it's not, first of all. It may be the real-time Sawyer, but it's not the band Rush. It is a Ruby shell with Ruby syntax and idioms written by Adam Wiggins of Heroku. It's got all the Ruby goodness from globbing to arrays to enumerables to anything you can love about Ruby. Hopefully you'll love about Rush as well. It's really, really easy to start using Rush. You have to gem install it and then type Rush on the command line. Just as a way to read this presentation from Q-on-R, any time you see a dollar sign, it'll be the Rush shell. At the bottom here, it's on the Rush shell. You say Rush home and that's your home variable, but as you can see, there's one thing you have to get over in Rush that is different from most shells, and that is that there's no working directory. So you don't CD somewhere and then do your work. You have a variable and you have two variables to start off with. You have home and you have root. Home, as you might imagine, is your first home directory and root is slash. And then from there, you can assign it to, you can go home, then whatever you're working, your working directory you want to get to, and that's sort of how you operate in that directory, is by kind of square bracketing to that directory. Ls, you can still use Ls, even though there's no working directory, so you go down to it and then you operate right off of that directory. So this is going to be sort of a theme throughout the rest of it. You're always going to be sort of operating on Rush directory instances, rather than working with like paths to things or in working directory. So it's kind of a hassle to always go home, mydev, github, rushmate. So what you do, like I mentioned earlier, is you would assign it to a variable. So from here on out, rushmate is that path. So you could just do rushmate.ls from here on out and it really shortens things up. And rush is a shell and it's a command line. You can do a lot of the same things you can with bash or zshell or whatever you use. But I was going to kind of go over some of the rush equivalents to things you're probably used to, like renaming a file. In rush, you have your rushmate, which is a directory instance, in my case, this is the variable I assigned in the last slide. So my directory rushmate has app models, rushmate.rb. So from there, if I want to rename that file, I would just call .rename on it and then pass in the new name of it. So you're always dealing with sort of instances of things rather than sort of a working directory. So your working directory is basically you have instances of everything and they're always in memory. So you always have like all your 10 directories that you normally use. You can just assign those to variables and they're always sort of in your working space right there. Duplicating a file, it's basically copying in the same directory. If you decide you no longer want straight text of readme, you make it a markdown file and it just duplicates it with all the same contents and it's copying the same directory, you guys understand it. Moving into a different, copying into a different directory, you take your directory instance, then you get your file out of it and then you tell it where you want it to go. So in this case, other project refers to another rush directory instance. So you're copying it from one rush directory to another rush directory, which is, you're always dealing with these rush directories no matter what you're doing. You don't deal with full paths that often. In this case, I want to move the readme file to the desktop, so I just say file.moveTo and then home is one of the built-in variables and then desktop is off of home on the Mac. Which, since there's a Mac talk going on now, I assume there's no Mac users in the room. I was kidding. So if you wanted to write a file in rush, you just grab the file you want and then you do .write and pass in a string, just like Ruby. Exactly like writing a file in Ruby. You get an instance of that file, you write it and it's there. And then to read it, you do .contents. And this is just all pretty much boilerplate stuff of like how you interact with rush to do things that you already probably know how to do in bash. This is where rush really starts to get interesting for me is Ruby's file globbing is pretty cool and to be able to use that in the command line is a big win, I think. So here's a basic glob. You just say the directory and since you have square bracket glob, just like dirt globbing, and then you say, you know, star, star, star, star, rv. You get all the Ruby files and then they're returned to you right there. And what you can do with that is where it becomes fun. Just globbing isn't that great. But when you say I want to open it in my editor of choice. So you say rushmates, you know, you glob to whatever you want and you say .vi, which opens all these, all the hits. All the hits into open to vi buffers. Or if you do .mate, it creates an ad hoc project with just those files in the project drawer. So you can operate, you can search and replace, find, do whatever you normally do in textmate with your, but just on those files. You can operate on the results straight in rush. You can say, get me all, and this is an example I have of like a legacy Rails project. You can say, get me all the RHTML files and rename them to html.erb files. And you can do this because you can just each, like any other enumerable, you can call .rename on each file and then gsub with regular Ruby gsub, which is pretty powerful. So anything you can do basically in Ruby, you can do just like, huh? Did somebody have a question? Okay, sorry. So yeah, so anything you can basically do in Ruby, you can sort of do in the rush command line. And it's really powerful because Ruby is really powerful and that's why we're all here. There are, like I said, there's straight up arrays, so you can reject things, you can concatenate arrays, and you can operate on the results of those all right in line. So anything you can do in an array, you can do on these results sets, and then call .vi or .mate or .you know, anything you can do. I use rush on the command line some, but embedded in other things more often. Like, and in this case, you can see that if you put this in any file, you can, you just require rush and then you put this in any file. Anything where that comment is acts exactly like it's on the command line in rush. So you can, you can, you can embed it in a Saki task. And what I've done, what my use case was, I wanted to say, I want to know about all the R docs of local gems on my machine. Just so that I can look at all the versions of R docs or if I don't have internet connection, whatever. I wanted all the R docs locally. And so what I've done is I made a Saki task called R doc local. And the contents of it are less important than the fact that it's just five lines of code to find all the index files of your R docs, all the gems. Then you make some HTML out of it, write it off to a file, and then open that file in a browser is, is the idea. And that's, that's, I just got every line. You find all the files, make HTML out of it, write it to a file, and then open it. And the results are pretty cool. So you run Saki R doc local, and then it opens a browser window with a link to all your, your local gems. And then from there, you can click on any of them and get to the R docs of your gems. And it's all local. It runs really fast. But that's, that's all handy. And you could have done all that in Ruby, obviously, but you'd have to require different things and, you know, look every, it's, it's just all this stuff is sort of mixed in and works like you're on the command line. And it's, it's a lot shorter for me to write it this way than it would be to use straight Ruby. Another thing that rushes is really good at is, is helping you refactor or, in some cases, you know, doing some of the operations for you. You can search for, you can, if you've globbed to the files that you're interested in, you can search for anything using normal Ruby regular expressions. So you can say, find in these set of files, find any reference to rushmate. And then what it gives you, the output it gives you is the line hits, sort of like a grep would. And it, it, it highlights the hits, how many files matched and how many matching lines there were. And from there, you can, you can still use that and you can still call all the normal things off of that that you could before. So you do, you can call mate, you can call search again if you want. You can just, you can keep kind of chaining this together to build up a, build up your, your search results that's however you want. And, and then if, and you can use the normal gsub across files, across projects. So when you do this, you know, glob, you can say replace the contents. Anytime it says, anytime you find this regular expression hit, replace it with this string. And it's, and this is like a, a project, search and replace. It's, it's one line of code. It's, it's really the equivalent of doing this in other things on the command line is a little bit worse, I think. So this is just really, a really powerful way to do refactoring. Let's take a little bit more complicated example of what you can do with refactoring. Let's say you have this line of code scattered throughout your project. It's user to authenticate password user. And like a good programmer, you're a little anal retentive and you say, well, users should really come before password because that's the way the user would type it in. So you want your, you want the code to look like this everywhere in the software. Well, because swap parameters is, it's not that fun to do by hand and it's not that easy to do otherwise. But you can sort of do it with, with the power of gsub in Ruby. You can say, find all the project files and replace it with, this is a little bit of regular expression magic that you have to sort of go through. But you find, you find, you find all these calls and you swap the parameters. That's essentially what this does, project across the whole project. Processes. Another thing that is very common on the command line is PS dealing with processes quite often. PSing is not that fun to do sometimes with like looking for a specific process and finding a process ID and operating on that process. It's, it's a lot of, I guess, said, maybe an awk. I'm not really good at it. That's why I like rush. So what you can do after you get the process. So at the top thing, processed up filter, it looks at the command line, it finds the Firefox process. It returns the first instance, the first process that matches that. I should back up just a second here and say that processes is a, is a method in rush that returns all the processes. And lets you, and mixes in a filter method onto that array. And lets you sort of filter those processes based on command line, memory usage, process ID, user, CPU usage. You can sort of filter on all the, all sorts of different things. And then once you have a process, it becomes trivial to ask it questions. Like, are you alive? How much memory are you using? What's your process ID? How much CPU are you using? And if it is Firefox, eventually you just call kill on it, because it's taking too much memory from you. And in a real world example, along the same lines, this runs in my chron tab. It runs every night at midnight and checks if Firefox is over 400 gigs of memory, kills it and restarts it. It's not as, it doesn't hit as frequently after Firefox 3, but it still does hit. And I still get to work if some warnings, and it has, you know, Firefox is quit unexpectedly. Would you like to restore your session? And you restore it, it's fine. Everything goes back to normal. But, so what happens in this thing, just to give a quick rundown of this, is I say filter the processes, find the Firefox process, check if it's over 400 megs of memory, and then grab the command line that it was using, kill it, and rerun the command line in the background using bash. And you can just, it's just, you know, like, six lines of code to kill Firefox and restart it when it stops behaving properly. I, it's, these are really simple, small examples. There's lots of examples on the rush site that are, you know, good as well. Rush also helps you with your permissions. It's a little more verbose than, than bash. I still tend to use chmod personally, but this is very readable. And so a file, this is a file instance now that we got, like, the readme example for. So it's project square record readme is a file instance. And then from there you, you have a dot access that takes a hash. And you can just tell it with the user or the group, or the user and others, a group and others can do. And then you can query it for its boolean status, basically. Whether or not, you know, can a user read, can groups read, world read. And that's, it's, it's pretty straightforward. It's just permission stuff. And Rushmates, it's still a .42 release right now. So it's not everything you might want to do on bash you can't necessarily do, but you can always call bash from your working directories and pass in your, so this would run rm-rf.inside the working directory Rushmate, which you most likely don't want to do, but you could do it if you wanted to. Another interesting feature of Rush is that you can, you can, you can be on your local terminal, shell locally, and you can act on any other server across a, across a sort of bridge. So the way you do this is you establish which box you want to talk about. And then you say, on that machine, you know, look at the revision of whatever that server is set to and print it out. And this is all right on your own local terminal that you can do this. And I always caution people using this because it opens a, it starts a mongrel listener on the remote server. So I would, I always caution people to use it in production, to use it with caution in production, I should say, caution people to use it in production. But so I think it's interesting. I don't use it all the time because I don't like, I don't use it in production, but it is interesting and it's cool to be able to use it on QA and other machines to sort of query, query things on the server. And when you have a remote, that refers to slash, like root does on your, when your own machine. So when you open a box, it refers to slash. As in bash and other shells, you usually have a big RC file or a login file that has a lot of aliases and paths and other, other things set up in it. And you can do the same thing. You can set up all your working directories or your instance variables you care about by saying, all right, in, in set up, whenever I start rush, make sure you assign this directory, assign this remote box. It's just a really convenient way. You don't, you're not going to have to do that, get down to your main project. I have like 10 directories I use all the time and I just put them in my, in my environment file and it's, it's good. It's set up and ready to go. In this, you can also add commands to rush in your environment. And you can do this by saying, just define a variable. And this, now anytime you're on the rush shelf, in mine, because I have this in my back, in my ENV file, you could say, cheap backup and then pass a rush directory in. And it's, it is exactly what it says. It just renames or duplicates the file with .back basically. It's cheap. It's, it's throw away. It doesn't, you know, solve a lot of problems, but it is so cheap to do that you just define it in there and forget about it forever. This is a very interesting thing about Rush. You can extend how, you can extend the glob, the arrays that get returned from glob, so that you can say, you know, on that array, like there's a .vi and a .mate command, you can add your own commands that, that operate on the directories or files. In my case, I added a .coverage that calls rake coverage on my, on my directory. So now I say rushmate.coverage and that just runs rake coverage and it's just a simple throw away thing. But now any, any rails or Ruby directory I want to run coverage on, I just do that directory.coverage and it's, it's a, it's just, it's just there. You can also add, and like I said, you can add more commands to this file and I added a little shortcut to redefine star, star, slash star, the glob that I've been doing the whole time, .rb, that is called Ruby files. And it's, it's a named, it's basically a named glob in this case. And it's actually longer than actually globbing straight, straight out, but it's more readable and easier to type. I'm like, I'm right there. I have, I have a text mate example and it's going to be a little bit text mate command specific. So if you're not really familiar with them, just bear with me and I'll try and explain it. But in, in text mate, I, in Ruby when I'm writing Ruby code, I name my variables the same as the class a lot of times, like user variable refers to a user.rb class usually. And I, and I often think to myself, wouldn't it be great if I can just, you know, and ID my way to this file with a command click. And I sort of did that with, with, with a rush and rush mate as an extension. So what it does is you type a file, it looks in your project, finds a file with the same name.rb, and then either switches to it or prompts the user if there's multiple hits on that file name.rb. And it's, it's really simple to write. You'd think it'd be a lot of code, it's like 10 lines of code. It, and you could do all this with a text mate command in Ruby, but like project directory on the, on I guess the third line is an environment variable that text mate exposes that returns a string. Whereas I wrap that and I said, return me the rush directory instance that that string refers to. And then from there you can glob, just like, like normal. So you could say project directory, find me the current word.rb and then, you know, check if there's multiple, open it up in text mate. Basically it just switches to it or prompts the user basically if, if there's any, sorry, if there's any, like if there's multiple it prompts the user and user selects and then it switches. Just like the example here. In this case there was two. There was one in models and there was one in shudda, the plug-in. I ran super short. Okay, so the takeaway of this is that anything you can do in rush you can do in Ruby basically. It's just, it ends up being a lot shorter and there's a lot of mix-ins and there's just a lot of shorter things in there that make it easier for a user to do without requiring things requiring file utils, this and that. It's all sort of mixed in for you and really, you know, one-liners easy to comprehend. Any other questions? You were first. Go ahead. There was this notion of being able to sort of almost come out of a remote system so you could copy things from one system to the other much the same way you could copy a file from one directory to another. There was an invent? Plan nine. So the question is, does rush do that? Yeah, does rush make it? I mean I guess the correct Ruby code to do it but I'm wondering if it was already built in to be able to copy things from clearly to not have to make instincts between copying a file from one directory to another of a local system and copying between say two remote systems. That seemed to be crazy useful for society. Okay, so the question was in plan nine there was this idea of mounting a remote system and sort of copying between them via like other remote systems or local systems and does rush support that? I don't think it does at the moment. I'm not sure how hard it would be to implement. I'm sort of just a fanboy of rush but I don't think it does at the moment. It might be possible though. I don't know if Adam said he might be able to show up. It does support that. It does support that. Well there you go. It supports that already. Problem solved. That's where it will be. Okay, so what's the next question? Regarding that remote, is there the assumption that the rush gem is installed on the remote machine? I think yeah, that's the assumption. Any other questions? Can you run most of this on Windows as well? Yeah, I think I'm pretty sure it works on Windows. To air handling and dealing with return codes. From BASH? Yeah. I think it assumes a return code of one and I'm pretty sure that's the case and it's zero? Zero, okay. And it's sort of, I think it assumes the return code of zero. I'm not, I haven't run into too many issues. Like get status sometimes is giving me some issues when I was running the get command, but yeah, I think that that's its approach. Dan, you mind what? You embed a search in a embedded thing. What would you do, Rebecca? Right, the search does, the output is the, I think it's just an inspection of the array. That's what the output is to rush. What you would get return if you embedded that would be an array, I believe, an array object. Where do you get it? You can get it at, You can su gem install rush, or you can get pull it, but gem install is just simple. I can't get that, yeah. Paging? I don't know. I'm not sure. I don't think so. Is there any other questions? SUDU, I've experimented with it. I've had, I haven't really gotten it to work very well. Maybe I just don't know the tricks to it, but when I tried it, it wasn't prompting for password and things like that, so I don't think it supports it quite yet. You can also pass a user into bash, and I think it'll run as a different user. I haven't really used it too much to tell you exactly how it works, but you can pass a user into bash. The command. Any other questions? I think you have a break now, so enjoy your break.