 Video equipment rental costs paid for by peep code screencasts. Hey guys, my name's Yehuda. There he goes again, refers to the fact that I'm going to be doing some live coding at the end of this, but not the whole time. Also the live coding is going to be more audience directed, so it's going to be more showing you random features and not trying to achieve something. It's probably going to help. My audio is very distorted. I'm going to move my mic down. Okay, does this help? Hello, is this better? All right. So, my name's Yehuda. I work at Engine Yard. I work on Dayquery, Datamapper, and Merb, which are killer stacks. I've seen my children before. So, basically I work on all the technologies that I usually talk about. It gives me a good perspective to talk about how they work together and basically how to actually use them for real things. Some things about Merb, Merb is fast. Pretty much there, you can choose when you make a framework between fast and elegant and Wave does functional programming. You can try to make choices and it seems today that if you make or people have made the claim that choosing speed automatically means you lose elegance or you lose other things. Turns out not to be a zero sum game. Turns out that if you decide up front that you're going to be fast and elegant, that is possible to do it. But that it requires significant amount of thinking and work and we do that. Basically, slow is not allowed in Merb. A lot of people say, well, I know inject is slow, but you should just do that and boot up or something. It turns out that when you write code in a framework, especially an open source one, it is extremely hard to figure out in advance what code is going to make its way into the critical path. So if we said, oh yeah, we'll allow super slow stuff in boot up, some guy is going to make a patch sometime down in the future where he copies some code out of the boot up and puts it somewhere else and everybody else will say, sounds good, it looks like it comes from elsewhere in the framework. So we pretty much don't allow slow code anywhere in the framework, which leads to really fast code. Leads to Merb requests rendering in 500 microseconds. It leads to things like it seems like controller set up cookies, there is 75 microseconds. That seems like a lot. It is a lot. It's going to get smaller. But it's good when you're thinking about things like 75 microseconds. There's a lot. That means something. That means that your app has a lot more headroom than other things. It means that your app will be able to actually do things. Let me rewind. So Merb is frequently used for things like ad networks, where you get 10 million hits a day or 20 million hits a day. In fact, there are Merb apps running today that get into 10s of millions of hits per day. That's only possible because it's possible to write Merb actions that render in less than a millisecond. It's not actually possible to write Rails actions that render in less than a millisecond, because the Rails stack is two or three milliseconds. So what else about Merb? So there's this thing called the public API. That sign over there is sort of what has happened to Rails. So you have to decide when you're making an app. Usually in most languages you have to decide what the public API that you're going to expose to the users is. And a lot of languages like Java provide facilities where you can say, this is private and you can't touch it. And thankfully Ruby doesn't do that. Ruby actually lets us experiment and do all sorts of interesting things with things that the person who wrote the original code might consider private. What that lets us do is it lets us say, okay, here's a bunch of code and it lets other people write plugins or experiment and come back and say, hey, without having to write, recompile or do any sort of, without having to do any sort of hard work to get it running, they could simply at runtime make some changes, see what happens and then come back and say, hey, you should make this change. But that doesn't mean that we should give up on the notion of what an API is. So MIRB has a strong sense that there is an API that MIRB intends you to use made up of all the public methods in MIRB. And there's also a bunch of other methods that MIRB uses internally and you should not use those methods. Obviously that doesn't, like I just said, that doesn't make them verboten for experimentation. But it does mean that there's a contract with our users that we make. You only use the public API, we won't change it, and we're going to make it super robust. What that means is that if you find something that you can't do with the public API, we're going to make sure that you can do it. Usually when I say that someone says, really, anything, the answer is probably not anything. But our mission is to not use Ruby as an API. It's not to sort of expose all corners of the API and then let you do whatever you want and then forever maintain every private method as an API, which is sort of Rails' position right now. Because of the fact that people have overridden, you know, the way that Rails looks up dependencies in order to add special functionality, Rails can't change the way they look up dependencies anymore without breaking people's apps. So we're going to, we're trying to avoid that. But we're committing strongly to if there's something that you want to do that's relatively sane, adding it. One example of that is MIRB made an assumption for the first two years of its existence that templates came out of files. Seemed like a really good assumption. And then one day someone said, I want to put templates at the bottom of my controller. But I've started it since Anatra. It's been cool. And our first reaction was, this seems crazy. But then our second reaction was, why are we making an assumption about files without templates being the files? And it turned out that by modifying our API so that it no longer made that assumption, we didn't have to add a lot of, it was, you know, a couple lines of code. We changed the way our assumptions worked. All that code was already private. And we were able to give this person a feature that he wanted without having to, without him doing what he initially wanted, which was alias method chaining render, something like that. That was his initial. He said, this was one of the times when someone came into the merge out room and said, I came up with a really good reason. I have to use alias method things. I found the reason why you need it. And this was one of them. And the solution was a very simple two line change that changed the fundamental assumption about how Merb worked, but didn't break anybody back. Merb is modular. What that means is that pieces of Merb don't know about each other. Really. That is sort of a fundamental way programs usually get written, but somehow, because Ruby is powerful and flexible, lots of code written in Ruby doesn't end up being modular. It requires discipline, but what it means is that you can easily, if you want, swap in and out pieces of Merb, which leads to very hackable. That's Roomba. Roomba actually decided that they are going to promote people hacking Roomba. But they could have not. They could have said, this is Roomba. You can't touch it. They could have been Apple and said, if you open it up, they didn't. They actually have a place on their site where you can download pictures of cock fighting Roomba. That's actually sort of our same approach, which is make Merb as hackable as possible. Make it a framework that, if you're a hacker and you want to make the change, it's going to be really easy. You're not going to have to go walking through the code base for several days trying to find something to be obvious between modular, etc. One of the things that came out of this is Merb slices. What Merb slices are is a way of taking a piece of your app, so let's say you have a blog and it has the same three controllers, two models, a bunch of these, some routes, actually get all up into something that looks like a Merb app and then distributing it as a gem. It actually ended up not requiring almost any changes to our public API. So we had one change. This was a big feature. It was a people wanted this in Rails forever engines sort of provided for breaks sometimes and seems like a big hack. So we were willing to make some change to the public API but it turned out we didn't need to because we already didn't make any assumptions about where files live or where controllers, models, or views should exist or how and when to load classes. And so everything just worked. And the person who wrote slices who is currently doing a bunch of really interesting work in Merb actually getting paid by engineers to do something in Merb has said that without the way Merb's infrastructure worked he wouldn't be able to do it. And I think he wrote slices in like a few days or for sure under a week. So that's pretty cool. And that's sort of a testament. This was the first testament. This was the first time where I knew for sure we were right on what we were trying to do. So people sometimes say, well, it sounds like you're getting all configurable on me. So put that. Do I need an XML file? And the answer is no. We like convention over configuration. So here's how Rails does convention over configuration. They have Rails and then they splatter throughout Rails all the convention. So that's one way you could do it. You could say 20% of people want something done this way. We'll just hard code it into the framework. These rollers are supposed to be in app controllers. We'll just have it in the framework that it's an app slash controller. And we won't really have any notion of when you want to say app controllers go somewhere it goes into a special place which is the default place. Merb works differently. So Merb has Merb core which has no default in it at all. So assumptions that you would assume would be true like models or are nowhere to be found in Merb core. In fact, if you would download in a small Merb core right now you would not you would not be able to make any sort of assumption about anything. You would have to pretty much start from the ground up. So yes, you would have not XML files but a lot of configurations too. But we're not EAs. It is true as Rails proved that a lot of people want the same thing. So we have layers on top that are seen and known that are Merb more which has a generator in it that generates files and unknown configuration. It has some template engines it has a whole bunch of stuff that adds features that sort of come with Rails but in their own little boxes. And then we have a layer of defaults on top of that which says okay, most people actually want their things in app models. So we have one file which is the bootloader which puts the defaults into place and it's the bootloader unlike Rails which has just one giant method which says do this, do this, do this do this and it's just one line like 40 lines or something basically if you want to change the way Rails stuff you're going to have trouble the bootloader in Merb allows you to simply just say okay I don't actually want the load framework bootloader so I won't have it. Just take it out and in fact the active record plug-in for Merb adds a bootloader into the bootloader in a specific place where it needs to be which adds its own set of defaults because obviously you don't come with Merb and that's sort of the way you like it so that's sort of the philosophical treatise on what Merb is and now I'm going to go into some cool features and then I'm going to do some code. So first of all the Merb router is pretty cool you can do stuff like this you can request that anything so what that route says is match flash-foo but only if the user agent matches MSI and what user agent matches MSI means is request that user agent matches MSI you can also do really easy optional segments as you can see here nested optional segments so you don't have to do weird things with splats and simply put optional segments in Merb and then you're good to go we also have something called deferred routes which is sort of the reason why this set of slides is in here deferred routes basically let you take a piece of code that is routing code sort of related to the way where you want to go and put it in the router block of code that gets the request and the parameters and we've actually because of the fact that the session is not really part of the controller it's just part of the request you can even do request.session so over here you do the request.session is logged in then send you to main merge main in controller main with parameters otherwise send you to log in sort of the request.session that logged in is also another interesting thing about Merb which is that the session is the first level object so in atmodel.session you can actually go in there and add methods to the session obviously we'll have access to self and actually do things like request.session instead of overloading helpers or your controller with things like log in plus and plus which obviously would then make them inaccessible for the route so one of those coming out October 11th I don't see any reason why we announced that a couple weeks ago and we're very much on target Merb camp is October 11th and the goal is to release 1-0 by then some things that are in 1-0 form builder with automatic client side validation so like Rails Merb has a form builder but Merb's form builder is actually really powerful and easy to swap in other form builders with anybody noticing so Merb has a plugin called Merb jQuery that comes with Merb more and obviously you can take out nothing is entangled into it but part of Merb jQuery in 1-0 will be a form builder that when you say input or text field who will go in to data mapper and I guess act a record to provide the same functionality that it wants to that would look for validations and automatically add the appropriate metadata in .gov and could do anything which would automatically then give you client side validation and the router that I showed before which didn't have like r dot blah blah or map dot blah blah is part of a ground up rewrite of the router mainly the mission of the new router was to provide better URL generation so the existing router is really fast the initial mission for the router was for it to be super fast but it is because of that super fast and super powerful because of that it's very hard to do URL generation that user agent MSI hard to figure out how you would go from a URL method and go to something that's in the router so it turns out to be really hard but it turns out that if you operate within a subset of the allowable routes and we're trying to make this subset as big as possible then you'll be able to generate routes from the client side we made a decision with the new routes not to to not really support URL generation of anonymous routes that may sound really scary it turns out that you should be in rails also using named routes because they're much faster for URL generation so like we're talking milliseconds of time that could be spent in a reply to a lot of URL generation purely just generating routes because you have to go through a massive list and start figuring out what's going on and okay which one is the least ambiguous or all sorts of crazy rules so turns out you should be using named routes and MIRB is going to enforce that you should use named routes for URL generation with the exception of the default route that has its own name closed as well so you can do URL and you can do like controller through action bar and that'll work fine because it's the default route but otherwise you should do the thing that's best something people have perhaps criticized MIRB for I think it's fair to criticize Ruby web framework for this because it's really hard to figure out how to test things MIRB has some nice things in it like the fact that you can instantiate controllers usually you can do controller.new and then you can call an action and get the method and it turns a string cool but we still don't have a clear testing strategy there's a bunch of people doing MIRB apps though and we're all testing our apps so before we know we'll get together and form up what appear to be the best practices this is definitely going to need to be something that I don't know what to say because it seems like obvious that we as a community care about testing but it seems like there's big holes in what exactly we care about and how likely we are to actually test in a way that so in my view testing should be that when you find a bug when you create a bug a test fails and when you do not create a bug then it's going to fail and now we're near that in the Ruby community pretty much all testing strategies produce test failures when there's no bugs and we need to not do that so hopefully the MIRB testing strategy will be closer to that but I think we need to step up as a community and get closer to that ideal there's also going to be something called MIRB stack so another criticism of MIRB is like I said oh my god which we don't have but oh my god configuration I have to know about all these gems that are in MIRB more and what I need and it's going to take me days to even figure out to begin what I need and it seems like everyone's doing the same thing anyway so what are you guys doing so we agree that it would be good to have one thing that if you wanted to just get up and running it would work and everyone would probably do that so there's going to be this thing called MIRB stack it's going to be a meta gem that's going to be a developer and will also include a generator that will generate that will sort of free fill in the configuration for you so you don't need to figure out exactly what all the gems are what's kind of nice about MIRB stack though is that if you after generating MIRB stack would want to change up what you're doing it would be pretty easy because it's just sort of pre-filled in generation for example it will be really easy to take it away like I said much better URL generation this is as I said before sort of a combination of restricting URL generation to named routes and then making URL generation through named routes as powerful as possible again because we do things like matching user agents and doing deferred routes it becomes super hard to work trying to make it as good as possible a really interesting promising thing that we sort of spiked out and now are on the fast track to getting into MIRB is so fusion passenger is cool because fusion passenger lets you do fast restart they have all these forking tricks which they use and because of the fact that they fixed the forking problem in Ruby with Ruby Enterprise Edition they can do all these interesting techniques for deploying but we don't want to patch it most MIRB people don't want to patch it but they release this open source for Ruby Enterprise Edition so what we've been working on is getting a lot of techniques that are in fusion passenger into MIRB proper so one example is that when you load up MIRB in 1.0 it'll assuming you have fusion passenger installed otherwise it could be a bad idea it'll fork right before all your classes are loaded so it'll start off your app and then it'll fork off and then the parent process will just chill out right before forked off waiting for a signal and then the child process will go on and do its thing like works right now and so far everything would be moving along as expected as MIRB and Rails work today but then if you sent a hang up signal to MIRB for the child process the child process would exit the parent process would be reawakened fork again from that initial point so in case that wasn't clear what that means is that you'll be able to tell MIRB restart quickly and it will reload any file so you'll be able to do a deploy totally change the files that are in the tree tell MIRB to restart and instead of having to restart from the beginning load all your gems and all that stuff it would start just from the point where it has to load your classes which would be faster start we're also going looking into and this is tricky across all the servers being able to manage a whole cluster through one parent process so we already have this working for mongrel and to supply what this means is that instead of a parent process instead of if you want a cluster having the initial process sort of shell out and make a bunch of MIRB you have the initial process working for processes and be in charge of listening for the child getting killed for instance by monit and making new one so what this means is that because you also fork from in this case you fork from a much later stage so you fork from right after all your classes are loaded but right before you actually down to a fork so what happens is you have a process and all of a sudden it blows up to like 6000 megabytes and if you're using monit which most people are with God your process will get killed so what that means today for like a mongrel cluster is that your process gets killed and has to boot up from the beginning all over again which means that there could be 5, 10 or 15 seconds where one of your processes doesn't work what happens instead is that because the parent process knows what's going on it can simply just refork as soon as the process dies so you have a child process that gets killed the parent process is like okay I receive a sig tile make a new fork and then probably 100 milliseconds something without the new process anyway all that stuff is courtesy of season passenger actually releasing ruby as ruby enterprise and I would encourage people interested in like long lasting ruby processes in general to strongly consider the possible benefits of forking as she's working I know it's been like a long time that forking hasn't worked in ruby so sort of the conventional wisdom is that things don't work it seems like a crazy plan but it actually worked with ruby enterprise seems like something worth considering another thing that we're doing with forking is code reloading sucks in everything because ruby has side effects if you say require some file who knows what it does might require another file that will do crazy things you can't really just say like unload the constant but Rails sort of enforces this notion that you can only put a controller and a controller file but as probably everyone in this room knows if you find a mistake don't do that very scary and bad things happen Murobb sort of tries to get it better by tracking what constants are loaded when you load a file but even that it's impossible to track every single possible side effect so what we're doing now is we're going to try also because it doesn't really matter how big your development process is so we fork really early again and then if we detect that a file is loaded we just kill the child process and start again and ruby loads in less than the amount of time it takes to push back your browser so what that means is that you have actual reloading that is perfect and foolproof again something that because forking is sort of a verboten concept and ruby people haven't thought of but once we started thinking about what forking to let us do the cameras a lot of really interesting ideas so I'm going to do some live coding well here's what I mean by live coding I'm going to make a verb app and I'm going to show you I consider doing slides here I consider showing you an action returns a string and hoping that you would understand what that means but it's actually really hard so what I'm going to do instead is I'm just going to make an app and I'll do some things hopefully directed by people wanting to know what things work and then hopefully you'll know what's going on so let me re-mirror my base before I do that are there any questions this is sort of 096 the verb right now is on a two week release cycle usually the weekend is the release so today or tomorrow there's going to be a release of 096 and so things like the new router are probably not going to be merged into 096 but it will probably be in 097 so pretty much everything I said in 1.0 is on the roadmap for a release between 096 and 1.0 so alright I don't mind that so let's make a so first of all if you say verb gen I'll just sort of give gives you generators we used to use ruby gen but we stopped using ruby gen because it has a dependent and active support and active support is very scary when it finds its way into your app and somehow that was happening sometime so some guy wrote a thing called templator and he started using it and it gives us it so if we say a verb gen app it'll tell us sort of what we can do is it big enough by the way to make it good so here so let's make an app verb gen app loanstar so I'm making a flat app here because there's something interesting in it so what a flat app is because merb has no doesn't care what directories you put things in merb supplies a flat and very flat app or an app with a single file and directories what to use so the reason I generated the flat is to show you this template location thing with super-wide apparently it's not an 80 character of a violation so what template location so basically what merb does is instead of just assuming that your template is on a specific location merb has a method called template location that gets called inside of the controller by default it means the exact same thing that rail is used by template location but in merb you can override that if you want and make your template the way you want this is one of the things that merb flies as easy to deal with you can use this in combination with rails as template root so we also have template root we actually have template roots I think rails might have that now so you can use template location in combination with template root to do a lot of interesting things so here we are inside of a controller and you can see that index just returns hello so let me just turn on the mode process ah but we do not actually just have a route I have to say controller I don't actually have a controller okay I'm going to back out of the bone so I just generated that to show you the template location message so I'm just going to make a regular merb app in a regular merb app comes with the router it comes with people around now let's make a controller so like I said if you make a string here and say hello and then turn on mode so that's what you would expect it to do so hold on and this is just because if you do we want to view and we say hello here hello from template and we say render over here unlike in rails it doesn't do anything magical it simply returns a string so it says hello from template and if I was to do x equals render something like render plus render it's just going to say it but it's a lot of time to turn it so so that works you can also return back if you also if you do redirect so let's make another method called you know, redirect it say hello if I say redirect to render it works that also simply returns a string so that sets the header and what not but it simply returns a string so while in rails you would say redirect you know long star redirected and return because in rails this does something special and then you might have other stuff here so this doesn't really matter since we're at the end but potentially we might have other stuff so you might want to return in Mirb we do the opposite so we can also simply return a string now I'm going to do something that you could never do in a real app just to demonstrate something so let's say I have a global and it has awesome there and I render the global obviously this is going to work now Mirb has a facility called run later which is simply a background thing you can say you can put in there $ax push so this global is going to get awesome push into it and it's still returning $ax so I'm going to restart to make sure that my globals aren't so what happens is that $ax over here gets awesome pushed into it but it happens in the background so what run later does is it provides you a block that gets pushed into a background queue and you can do whatever you want in it and if I keep running it like I said I would not use a global in your life run later could be used for example sending mail because it happens in the background thread there's a queue object that gets these run later blocks pushed onto them you should not use it really for mission critical stuff because if your process dies you lose the queue so that sucks but if you have something that you want to happen immediately and you could potentially clean it up later like you could easily determine that mail wasn't sent and therefore send it if your thing crashes or if you have a thing that never crashes or seems suspicious to me then you're good to go it's useful for operations that you want to happen in the background you don't want to clog up your render so you want it to happen quickly but you don't really care about you don't really care about the reliability of them you're willing to accept a process dying before everything gets sent so that's this is all cool so let's say I raise an exception here so I get an exception stack trace which is cool the stack trace lets you specify what you want if you say by default it just shows you your app stack trace and you can see inside it but you could also turn on the stack trace from the framework which will show you merbstuff gems which will show you anything from other gems like mongrel you could also turn on the stack trace the merb binary and obviously turn on and off so yeah that's cool and you can also see parameter exceptions you don't have any cookies or mingrats so that's cool so here's a common problem so what if I want to trap exception into something special I want to send an email so merb has this thing called exceptions control let's raise something more useful like a knock sound let's go into exceptions and go knock sound and let's replace this with a knock sound so it goes and renders that that's fine and you can use this for anything you can use, you can catch any sort of error you can even catch regular errors so you can catch standard error I'm gonna show you something this is the last time I showed this people were confused as to how this works and it seems magic but it's not really that method so if you do standard error that action name what merb does is merb tries to detect whether an action exists in the exception controller that map this it's literally a six line method the last time I did this somebody said wow merb hates magic and that seems really magical and I literally pulled out the method and it just does a recursive look and returns no if nothing is found and so you can this is sort of a way to do a rescue since you're not in control of the stack a rescue of everything but here's another problem let's say you're sending mail and your mail error is out it is it's own error raise let's make a mail error so if you do that the problem, so this happens in rails this is an exception let's go back to instead of raising the not found let's raise a standard error standard error is going to go here so if that happens you get an error stack you get a two dimensional stack of the error so the first thing that happened was you had the standard error you can see the stack trace at that point you can do the normal things that you normally do stack traces and then after that you can handle it here so you can use this to handle for instance an exception order fire which we have you can handle the case where there was an error in the mailer, do something else like maybe dump it into a file called you know, bad super evil errors that I couldn't catch and send mail through because you don't want it going to the log you want it somewhere else that you can look at and be like here are the things that I didn't get mailed at so that's cool what else does anyone else have anything they want to see before I move on so what else can you do with Merb so I'll show you our provide syntax so in Rails and Merb Rails has this thing called respond to which looks something like this you say respond to to format you can do something like format.html format.html maybe like JSON some object so let's imagine we have an object and we'll give it a 2JSON which let's say returns so in Rails I'm just compensating for the fact that I don't have an ORM object here so you might have something like something equals something.new and Rails would have this respond to block and it would handle it correctly but it turns out that you do this a lot anybody does Rails apps here which I seem to do this pattern happens a lot and you're constantly having to say well if I want to accept JSON in this case and if I want to accept HTML and you're just doing the same thing over and over and it's quasi-dry because at least you don't have to have a case theme or something but it's not really as dry as it could be so what Merb does is Merb has so you say in your class provides JSON and you don't have to say HTML, HTML is automatic you can say it does not provide HTML if you want but by default by default we provide HTML so and then instead of saying render or something like that you say display something and so we're in LoneStar and we have an index here so the first thing that display something does let's do the first thing it does is it gets your content type so let's start by assuming our, by the way Merb will tell you if it tries to remove a constant this is obviously pre the forking reloader and on Windows or some other platform doesn't support fork so if I go to LoneStar we see this thing, something so the first thing it does is it finds your content type in this case it's HTML and it says ok try to find a template called index.html.erb it found it so it found it and so it ran it but let's say I ask for JSON I'm going to start that JSON I love Firefox it's not any better so that's the JSON that came down so it's step one is it says ok what's my content type if it's in the case of HTML it was HTML it found the template all as well it just rendered the template if it doesn't find the template the next step is to attempt to try to call 2JSON or 2 whatever on the thing so this is the equivalent of render something or just something.2JSON right if I was to do this right if I was to do that now it's HTML because Merb accepts strings that's fine right so what display does is it encapsulates the pattern of that respond to blocks that Rails uses the fact that what you almost always what you pretty much always want is check see if there's a template matching the content type if so render it if there's no template then call 2 something on it and the 2 somethings are also just a layer of default that are provided by default in the bootloader but you can add your own MIME types just looks like this Merb.add MIME you say like shockwave 2 shockwave and then you provide a list of it's like application awesome x shockwave or something and this part over here tells it what you care about what incoming accepts headers should match this tells you what to call on it and this tells you what to look for templates so it would look for index.shockwave.erb so what if you don't provide JSON and you ask for JSON so it explodes with 406 not acceptable which is just coming here so I can say 406 not acceptable and then it will say 406 not acceptable so that goes back to the fact that you could catch exceptions another common question is ok so let's say I have something like so if I have this and I say 404 not found right and I go into lonestar let's say I raise my sql not found I want it to probably do this right because it's not the error but so far I've not shown you any way to disambiguate between that error and any other error because we only use the last part so we considered not only using the last part but it seemed silly because it seemed like the number of cases where this would happen would be low compared to the utility of having short names but you can just do def self.action name my sql not found right and then it will work that's because action name again is not anything magical it's just a recursive lookup for matching things in the exceptions controller so if you override it to something special it just works fine works just just the way you want so what else I'll show you action arc so what's an action arc so let's say I have in my lonestar thing I actually want to take a parameter let's say I want it to you know prams awesome right and if I do this I can do awesome equals lonestar and it will render it that's the normal pattern that works just as well in merb as it works in rails but rail, merb also allows you to do this right it lets you specify it as a parameter it even lets you do this and it does this using parse tree which a lot of people think is crazy but this is actually probably the most magical thing merb does and it does this because it provides a completely non-magical tsl right it provides a a mechanism for you to treat your controllers as though they were really actually ruby and what does this do for testing right in testing you can actually do this right that'll work that seems well worth the fact that we're using parse tree and both Rubinius and jruby have added to their implementations a non-par tree dependent version of dot arg so the way this, the way I would like this feature to exist if it was in ruby is something like you'd be able to do method index dot args and it would return something like this and yes I'm aware of the fact that if it was not a literal it would have posed some problems but assuming it was limited to literals which is the only case I actually care about something like this would be cool and that's in fact the api that we provide using parse tree and that's the api that is provided using rubinius and jruby which is cool ok so one thing that we do that sort of departs from ruby a little bit the ruby's normal behavior a little bit is that we do this so let's say x y equals hello z equals one star and let's say we did so first of all if you provide no if you provide no parameters in this case it returns a bad request which basically means you try, you try to call the method using without an x but ruby requires an x so there's a required parameter here called x you didn't provide one so boom bad request which is an htp error if I do like x equals whatever then it works fine what is not intuitive and again a departure from ruby is that if I do this it actually the middle it's able to call this leaving the middle default there but overriding this one that's just because of the way we do the lookup and the way we do the sends we actually just explicitly say ok we know what the default is so we'll send that in this case whether or not this made sense because it seems like it should just do what ruby does but it turned out that it's extremely common to have optional things and because we don't have to worry about the normal keyword arguments problem normally ruby has no way of specifying keywords arguments so sorry you're out of luck but in our case we do have a way of specifying them so we implement this as though there were keyword arguments cool any questions yes sir we support so if you do ok there's two questions there's two questions you're asking one of them is just in general how do we handle JavaScript like returning JavaScript back first of all as a person that does a lot of JavaScript I'm uncomfortable with the way Rails does it namely actually sending back JavaScript to be eval because it seems like sending back stuff from the server to be eval on the client side is bad like the is used on the client side to eval things which means that you're causing like this trust barrier that seems dangerous and I just I try to avoid having eval arbitrary strings in my code in JavaScript that just seems like a bad idea but so you can do something like provides js right and then you can do and then you could have you could potentially have it do like so this is not going to work because like I said there's no eval rigged up on the other end so I think it'll just probably return a string so it just works the same way anything would work by the way in my in this demo here I'm sort of cheating by appending .js or .json or .whatever that's because if you like in Rails if you do .js or .json or .whatever it'll automatically win out over any content that's provided by the accept header but if you do provide if you if you do this but you send in an accept header for instance if you're JavaScript or a web service we handle that just fine and that's handled using the list of accept headers that are provided by admi does that answer your question people tend to write JavaScript my 30 seconds should be on this is if you're a web company that has any kind of significant app and you don't have somebody on board that knows JavaScript you're silly it's like not having anyone on board that knows HTML so it's a core web language presumably you have a team of some people finding someone that knows Ruby and JavaScript isn't that hard so just do it if you look at 37 signals which sort of popularize RJS has a ton of custom JavaScript right so RJS is cool but they end up writing a ton of JavaScript on their own anyway because it's just not hot like Rails it's like a it's an 80-20 solution that is actually one of their worst 10% things ever and then if you in fact do use it at some point in your life you're going to be hitting a weekend and you'll be like oh my god I have to actually know JavaScript but I don't actually know any JavaScript so time to learn JavaScript over a weekend it's not ideal basically just get make sure you have someone on your team that knows JavaScript all be well other questions yes so actually this is a good opportunity to announce something so Merb typically starts up at around 20 megabytes for like these processes there's a site that had been running Merb for on a 40 megabyte footprint running a few three or four engine yard slices just getting like 7 million hits a day and I don't know probably had a couple dozen Merbs total on those four slices slices normally hold like three Rails instances so you could just pack more of them inside but the announcement is so I don't know if you guys noticed but if you require RubyGems and then require any gem RubyGems requires the entire RubyGems repository into your system and that could be a lot of RAM so just take double straight so here I am in IRB and that's here I am in IRB and it's four megabytes and let's require RubyGems and all is still going to be well I already required RubyGems actually that's fine but now let's say I require something small like JSON first of all did you notice that perceptible pause there and let's look at it now 9.9 megabytes so what happened there what happened there is that that pause was Ruby loading in the gem index into memory and that really sucks and that is actually the reason why any Ruby process involving gems that you run doesn't start instantaneously I can do like Ruby minus E puts awesome that will be instant and I think that's actually like a mission of Ruby is to be able to do that instantaneously or perceptibly instantaneously but once you add RubyGems automatically there's like a pause and that is actually unnecessary so what we have done is we're releasing a gem called MiniGem which is just all it does is allows you to instead of requiring RubyGems and it will does what Ruby 1.9 has something called gem prelude which mocks out a lot of the RubyGems methods lets you still say gem blah blah blah we'll still load everything it still adds stuff to the low path but it tries its darnedest not to load RubyGems ever because RubyGems is huge by the way I don't have that many gems on my system if you have a lot more gems than I do that number will be bigger that's possibly your process, randomly the reason we didn't just use gem prelude is that gem prelude works to avoid if I just so gem prelude was written so that in Ruby 1.9 that's still instantaneous because Ruby 1.9 has required RubyGems in it and so they didn't want to have it explode so it does sort of defer but gem prelude falls back to RubyGems way too often so for instance if you do in Ruby if you do like gem JSON bigger equals to 0.5 or something like that that works you don't have to do this in gem prelude the first one will trigger a requiring of the entire RubyGems library so there's a bunch of cases like that and so instead of trying to figure out how to fix gem prelude so that it would not so that it would work for all cases we just basically rewrote it something a little bit differently in that we require gem version so gem prelude has like a method that takes a string and makes a version out of it which is an array which seems silly since gem version isn't very large it's like a K or something and has all the functionality and so we did that a few times we also require the gem specification of any gem you actually load which is again very small so that we don't have to guess about where to require files from which is still possible using gem prelude but yeah it's cool and it's going to be released soonish like this week probably cool, yes so I have one minute so I don't think demonstrating is impossible plus I gave a talk about jQuery this morning but I can tell you the answer which is it's not any different from using jQuery with Rails jQuery has getimpost helpers, getimpost things and HX and if you just say dollar.get someurl provide a callback it will hit merb with the url it goes through the router then you probably want to ask for JSON so jQuery has like $getJSON someurl function JSON puts stuff in there and what you want to do is let's say we did like lonestar it's like the url you would put in the browser so if let's say I did lonestar index for instance with getJSON it'll actually so it'll go to lonestar.rb and if I say it provides JSON and you display something it'll return back to jQuery a JSON object which will be available as jQuery so it'll be available as json.awesome which is pretty much as far as I'm concerned all the integration that I need that pretty much lets you pass RubyHash directly down to JavaScript seamlessly and that I do a lot of good works well for me cool video equipment rental costs paid for by food screencasts