00:00:13.719
All right, so my name is Chris Wanstrath. I'm a little nervous. I've got a new operating system, and this is also the first time I've given a talk as a corporate representative. I don't even know how to say it well.
00:00:20.199
Well, I've given a few talks before, and in all the previous instances, I've always been representing like myself or a consulting company, or some big corporation whose website I don't even want you to go to.
00:00:26.960
But this time, I actually have a product that I'm really excited about and want all of you to use. So I'm going to try not to hammer it home too hard, but this is the product: it's called GitHub.
00:00:40.160
One of the things I read when I was researching how to be a good presenter is don't ever talk about yourself; no one cares who you are. Build your reputation by giving a good presentation.
00:00:46.160
So I'm going to not do that and just say GitHub is really awesome. You guys should try it, and because it's awesome, you should probably listen to this presentation, which is entirely unrelated to GitHub.
00:01:06.040
That said, GitHub is a Rails site built in Rails. I started doing Rails a couple of years ago, and I've always done it on the side while I was learning how to program and getting good.
00:01:12.240
To me, what was interesting was that Rails exposed to someone like me, a web developer, a really powerful dynamic language. What I did when I was learning Rails was not read the Agile Rails book right away because it wasn't out.
00:01:24.320
I read one of the only three books that you could get your hands on, which was 'Why the Lucky Stiff's Poignant Guide.' I think if you get all the way through it, that becomes your entry point into Ruby, and you come out with a unique outlook.
00:01:42.399
This outlook is that you're going to write the most cryptic, most insane code you can, and it's going to be awesome, which is what I do. What's great about Wise's book is it talks a lot about metaprogramming.
00:01:54.000
I think there's a chapter devoted to it. He's got lots of great mnemonic ideas to teach you the basics, but he also has fantastic examples that you can follow along and use to learn the more interesting things.
00:02:06.439
Like, DWTH me’s array is one example, as well as an entire mini-site devoted to learning how to metaprogram your own mini RPG. For me, when I was in college trying to learn a real programming language for the first time, all I really had experience with was, like I said, the web and MUDs.
00:02:23.680
So doing this was really exciting and got into my head that Ruby was really powerful because it could rewrite itself on the fly. That's kind of how metaprogramming was presented when you read about it in Wikipedia and all that stuff.
00:02:35.080
These are four of the methods that Ruby gives us that expose the underlying implementation and let us do things that the Ruby implementers can do within our dynamic programs on the fly. Define method, of course, class, new, let's just create a new instance of a class.
00:02:48.159
We can pass it another class to be the superclass. 'Instance of all' lets us control the scope of a block or a string, and 'send' lets us send a message, which gets to the heart of Ruby's Smalltalk message dispatch system.
00:03:05.760
Here's an example of something that I hope to never see in a Rails app or some kind of production code, but it's really quite fun to do. We have a person class, and we grab the singleton, the meta-class, or the eigenclass, and we run through either a local variable or a method which is an array of arrays.
00:03:19.599
The first element is a name, and the second element is a proc or lambda. We add all these class methods on the fly to this class; there could be thousands in there, there could be tons, literally.
00:03:33.640
So this is really cool. There's a lot of power there. There are a couple of things going on: we have to send define method to get around the access controls because define method is a private method.
00:03:45.760
We have to grab this eigenclass Tom fery, which is probably a whole presentation in and of itself. But another great thing about Ruby is we can take this and make it look normal.
00:03:56.480
We can open up class, which is the blueprint for all instances of a class, such as person. We can add methods to it, which is something that Rails does extensively. Has many, belongs to, and all those are just class methods.
00:04:10.879
Then we get some Ruby that looks a lot nicer. It looks a lot less evil despite the fact that it still is. Ruby is very powerful for so many reasons, two of which are the amount of change you can inflict on the kind of environment at runtime and how much you can hide.
00:04:29.080
We just hid that tremendously; this almost looks normal, but it's really not. So this is one of the main reasons I love Ruby—these little side projects you can do for fun that are so far removed from web development or JavaScript.
00:04:40.960
I have this habit of trying to look for problems that aren't really that big of problems and solving them with metaprogramming. It's just something I'm into. One of these problems that wasn't really a problem was that during Rails development, I always have these rake tasks that I move around from app to app.
00:05:10.720
One was like DB version and db remigrate and stuff like that, which I could keep in their own subversion repository and do externals or have some bat script to install them or even a Ruby script that would constantly copy these rake tasks over from my existing Rails app.
00:05:16.759
But that was clunky, and I also made it harder to share these tasks with other developers, or to not share them. Maybe I didn't want to commit all my crazy rake tasks into the subversion tree because they were just for me.
00:05:30.680
Or I was too lazy to remove the hardcoded paths to my user, Chris, or what have you. So I came up with this idea for this project called Saki. It's the last effect I'm going to use, I promise, but I had to try out the new keynote.
00:05:47.919
So, it's like rake, except the first letter is different. What it is, is the idea of Ruby gems or any packaging system really, very lightweight for Saki. It's also really influenced by Git in that it's easy to use; there's no central location.
00:06:05.919
Every single Saki client is also a Saki server, so any file or any webpage which is plain text you can pull in rake tasks from. What I really wanted was to share my entire Saki file with anyone here.
00:06:18.680
There can be 100 Saki tasks in there, and I want you to be able to pick out just one. How do I do that? Well, there are a few different ways. Let’s take a look at this pasty patch I used to get back in the old days.
00:06:38.520
In open source, I would get lots of patches on Ruby Forge or wherever submitted as pastes. I had this automated workflow. I would pull in the paste, automatically apply it, run the test, look at it, and if it was good, I would commit it; otherwise, I would throw it out.
00:06:50.759
Now, that's actually all built into Git. This is one of the reasons I wanted to put this in there. So, you look at this and you know, how do we get just the body of this one task and identify it so that we can share it using Ruby?
00:07:02.240
We want to save it, we want to be able to install it, uninstall it, send it to someone else, or just send one task or a whole file of tasks. It looks pretty simple until you start looking at it.
00:07:14.440
The git format log is written in the curly brace style, and the one above it is all kinds of madness. It's simple, right? I'll just use regular expressions. It can't be that hard.
00:07:25.280
I'll find a bunch of rake tasks out there, get a set of regular expressions that handle every case, and I'll be done. But, of course, now I have two problems: regular expressions and the actual handling of them.
00:07:37.319
I was thinking about this for quite a while. I have another project called Cheet, which is another sort of fixing a really small problem in a really grand way.
00:07:48.560
It's a wiki where anyone can go and modify a plain text cheat sheet. They can add their own. There's one for subversion, one for Rails, one for TextMate, but it also has a command line client that you can use to pull in the cheat sheets from the website.
00:08:07.560
Because of that, it has an API. You can put it in TextMate or Vim. I have a little macro where I can pull in a migration cheat sheet into my Vim shell whenever I need it.
00:08:21.120
While I was working on that, I decided that it'd be cool to have a Saki website and be able to share these with other people. It's been in my head for a while.
00:08:36.240
One day I saw this presentation at a San Francisco Ruby meetup where a guy named Blaine Cook used a thing called Ruby to Ruby, and as soon as I saw that, I thought, I know what I'll do: I'll just ask Ruby what the method is.
00:08:53.599
I'll ask Ruby about that task, and it'll tell me, and I'll be able to do all the things I want to do on my own. It's funny because Ryan Davis is here, and I'm going to be talking about his stuff a lot, and I'm just going to try and pretend like he's not. So anyway, be nice.
00:09:07.920
Thank you, Ruby to Ruby is awesome, not just because Ryan's here, but because there's this really basic question which is really hard to answer: how do we ask Ruby for the method bodies or the bodies of blocks or procs or lambdas in this case?
00:09:54.720
I have a session here as 'forb' which equals proc blah blah blah. I want to get that self-referential kind of string into something I can use, maybe an array of this or that, or another string that I can re-evaluate.
00:10:01.880
So how do I do it? It's stupid simple: you just install the Ruby Ruby gem, and you call two Ruby on your block, and there it is.
00:10:14.680
So that's actually a Ruby string that we get of the method, the body of the block, and we can do with it whatever we want.
00:10:26.080
That's just one example of what we can do when we have access to this thing in Ruby, which we know as the Parry.
00:10:36.720
So the name of this talk is Forbidden Fruit. By the way, there's an apple; I also used the cool kind of remove alpha effect in keynote, which is really awesome to get that nice Apple gleam.
00:11:06.360
Moving on, Gstar Ruby to Ruby has a few dependencies, but the good thing is that once you install any of them, they pretty much all depend on each other, so you get it once you have to deal with two or three or four gems.
00:11:29.200
After that, it's a simple matter to install any one of the siblings. Ruby Ruby is good because it not only gives us the two Ruby method on blocks, but it also gives us a class method called translate, which we can feed into any class.
00:11:50.960
It provides the Ruby representation of that class. I saw Jil's presentation a couple of weeks ago at the Philly Emerging Tech Conference, which was really awesome.
00:12:02.720
There was about one table of people watching us talk, and it was all the other Ruby speakers, so I was paying very close attention.
00:12:16.280
What he did was he took an Active Record class, a subclass of Active Record, like a person class or a ticket class. He called has_many on it and then ran the class through Ruby to Ruby.
00:12:28.960
He was able to see all the crazy things Rails did to it—everything from 'has many tickets' to the options that it takes and where it goes with it.
00:12:43.000
It was really interesting to see these methods that you use every day, which you know because of the tests you write and the documentation you read in Ruby code, which I've never actually seen before.
00:12:59.520
So that was a really great use of Ruby to Ruby in my opinion, a cool way to just introspect code. He's not actually using it for anything, any kind of gem or whatnot yet, but it’s a good way to just see what's going on.
00:13:10.000
Back to Saki, I was going to do a little demo to show you guys what it is, but I don't think this is actually going to work. It worked so well in the tel because basically Saki lets you do -T just like rake.
00:13:22.880
It lets you do -h -T on any other file just like rake to see what tasks are in it. It lets you do -h -T on a webpage without caring about the difference and see the tasks in it.
00:13:43.560
It lets you do -d to install a single task, to install every task from a Saki file. -e actually prints out and examines the source of that task.
00:13:58.480
So let's say you have a list of tasks, maybe five or ten, and you want to see which version of 'git format log' is the best: 'git format log one' or 'git format log two.' You can just do -e git format log, and you'll see the code right there.
00:14:14.560
It's really cool because it just all works; everything that you would want to do if you were installing and executing arbitrary remote code, you can do. You can uninstall it easily, install it easily, and examine it.
00:14:30.680
It evaluates things over the wire with the safe level; it's just really great, really simple. And the best part is I wrote it in one night because everything is so clean and kind of just depended on other people to do the hard stuff for me.
00:15:02.120
To use Saki, this is what you write in a Saki file. Let's say this is what you and I see: task 'hello.' All of you should be familiar with this because it's basic rake.
00:15:15.679
But behind the scenes, what we're doing in order to grab this block of code and be able to treat it as data is storing this with our own DSL. So we're not actually using rake when we're running Saki and looking at this file with -T.
00:15:36.920
We're actually running our own Saki version of the rake DSL, where every task gets grabbed and put into our own task array the way that they do it with some extra metadata.
00:15:54.400
If we were to require Saki in IRB, we could do this: task equals new hello, where 'hello' is the task name, and feed it a body.
00:16:09.320
When we ran two Ruby on that task, this is what we'd get out: this would be a string, and while I'm printing it seems formatted nicely, it would be a string of the body.
00:16:16.040
What's interesting is that I didn't have parentheses in my version, but there are parentheses in this version. It's not actually saving the code you write; it's looking at something within Ruby, say the parse tree, and generating a string representation of that code, which is wicked awesome.
00:16:31.440
What we can also do now that we're building things on the fly is pass in some other information like dependencies and a description and get out a more advanced but very common rake task.
00:16:47.600
For example, there's a dependency on the environment task and description, and all that sort of great stuff. That's all I'm going to talk about for Saki right now. It's really great; you should install it.
00:17:02.479
If you haven't already, use it daily. There are a bunch of tasks for making Ruby development easier and using Git easier and whatnot.
00:17:18.480
But even though this is a Ruby conference, there's something that I learned recently. I've recently gotten into JavaScript at about the end of last year while I was working on this site, Spam for my other company.
00:17:37.680
I found jQuery, which Josh talked about earlier, and it's really awesome. It's just very concise, very terse, and very easy to learn.
00:17:53.200
You basically just learn a set of rules, and from those rules, you know everything. You know where to look for something, you know how to do anything, you know where to go in the documentation, and there are very few rules.
00:18:04.240
Everything is consistent. While I’m diving into JavaScript, I’m realizing, oh wow, this is actually a real programming language; it’s not just alerts and equals.
00:18:14.480
There's a difference between using a var in front of it and not. One of the things I learned along the way, which I never even imagined before, is that JavaScript has a toString function that's in every modern JavaScript implementation.
00:18:37.760
What it does is give you a string representation of the function. It doesn't work for things that are defined in C, like array size and whatnot, but if I define my own function, I can get back the string from it right there.
00:19:02.880
What you can do with this is the same thing you can do with Ruby to Ruby. For instance, Yehuda Katz, one of the Ember.js guys, has a JSpec library, which is a dead-simple BDD library for JavaScript.
00:19:11.920
What he does is print out all the statuses in the console of Firebug, which is pretty cool. He's able to print out the identity of the function you're calling and the name of the function you're calling by using toString and parsing the first line.
00:19:27.679
It's really cool. It gives you some insight into what you're doing, especially when you're trying to do kind of debug development or figuring out what's going on here stuff.
00:19:42.000
So Jim, and all Saki, that’s it. So, what else can we do with Ruby to Ruby? I mentioned it earlier, but Blaine Cook showed me something that was really cool and really opened my eyes.
00:19:53.160
There’s a gem that can turn Ruby code into Ruby code, and you're almost like, oh so what? Ryan Davis got drunk again and wrote something crazy that I'll never be able to use.
00:20:09.480
But really, it takes maybe one of his projects, one of Blaine's projects, or something real, something that’s actually being used in a project to see how really powerful it is.
00:20:25.560
This is one that Blaine did in about 30 lines of code. It's basically the map part of map reduce written in Ruby with Ruby to Ruby.
00:20:39.680
What you do is take a range, 1 to 100, and instead of calling map on it, you call dmap, which is this method that Blaine has authored.
00:20:54.640
What it will do is exactly what you expect: it will send this block to different servers that are running somewhere in the land. It'll ask them to compute it and get back the result.
00:21:07.920
At the end, you'll have a 100-element array with all your results served concurrently. The code is not the most beautiful thing to look at if you're not familiar with DRb and ring servers.
00:21:23.040
What Blaine has done here is two really cool things. He's forgone the sort of configuration you need to set up a little cluster of servers by using Ringy Dingy; it’s kind of like Bonjour for Ruby demons.
00:21:40.080
Servers can find themselves and clients can find them, so you can have as many as you want without needing to connect to this IP on this port or that IP on that port.
00:21:57.440
What Blaine does is connect to a Ringy Dingy server or instantiate one and looks for some other clients. This isn't using all the code, so I'm confusing myself.
00:22:10.000
The Ring server is a client. He attaches to the server and asks it to do something for him; he then collects the results and returns them as an array.
00:22:23.440
What he's asking the server to do is really interesting because he's saying, 'Here’s this block of Ruby code as a string. I'm going to send it to you, and I want you to eval it and send me back the results.'
00:22:41.600
This is over a very secure network, hopefully, so it’s not that big of a deal. The clients are identified by their PIDs, and it sends the Ruby execution element also serialized in the DRb fashion.
00:22:56.200
What you get back are the computed results, which is quite cool. Here’s the actual server end of it, and it just starts a Ring server.
00:23:12.200
What it does is take the strings off the wire, evals them, and passes in the element that was sent. If it’s 1 to 100, each time the block gets sent along with the element, 1, 2, 3, 4, and it sends back the answer.
00:23:27.480
It's really cool. It's just the map part of it. I'm sure no one’s using it, well maybe Twitter is using it, but I'm sure no one’s using it in production.
00:23:43.919
However, it's just an example of the neat things you can do with this sort of power. I put it up on GitHub last night because there is no reduced part of it, so it would be cool if someone wrote that.
00:23:57.960
I might do it later this week just to see if I actually understand what's going on. But there it is; it's grab-it octocat approved! What else can we do?
00:24:06.920
Well, it’s kind of switching gears here. What we're talking about is kind of beyond metaprogramming because metaprogramming isn't really that big of a deal or that distinct from Ruby.
00:24:23.680
Someone said that metaprogramming is just programming in Ruby, which is true. The methods that I showed earlier—the 'instance of all,' 'define method,' and those are well-documented.
00:24:36.960
Those are part of Ruby, so when you use those and you're coming from another language, they're magic. But once you start doing Ruby for a long time, they become something you kind of depend on in those edge cases.
00:24:55.440
There’s something that's always there; they're not special, they're just a part of Ruby. Ruby is just so dynamic that things are always changing, and you don't really even think about, 'Okay, now I need to switch into metaprogramming mode.'
00:25:09.200
However, there are limitations, and there are things that would be really cool to do, but you just can't; and what's really frustrating is that in other languages, some of these things are possible.
00:25:34.400
So, what am I talking about without using such abstract verbage? How can I make my SQL strings more expressive and prettier with syntax highlighting and whatnot?
00:25:50.720
The way to do it is to write it in Ruby. Here's one attempt; it's called the Conditions Builder and there is a plugin on the Agile Web Development plugin repository.
00:26:12.760
What it lets you do is spend time learning an entirely new API for the added benefit of some really weird syntax. But it's a cool attempt; it's writing your conditions in Ruby.
00:26:30.640
It's compositional, so you can take different condition objects that you've created and mash them together to get a new condition object. It’s probably very easy to mock and test, asserting that the SQL you're generating is the SQL actually you want it to generate.
00:26:46.560
However, the problems are obvious: you have to learn this whole new API, and it’s not that intuitive. This leads to the next statement on the list.
00:27:01.319
This is another earlier attempt, which is actually pretty popular. It's called Easy Wear, by Ezra and Fabian. The README file is really long; it can do a ton of stuff.
00:27:12.760
It lets you create your own Ruby DSL and enables you to create SQL conditions using it. Again, the advantages and disadvantages are obvious; it's cool and compositional.
00:27:30.080
It lets you do very complex things with Easy Wear, so you can pass in things like 'include' after the 'all' symbol to do your joins and whatnot.
00:27:49.488
But again, it's a whole new thing to learn; it's a really long read, it's very powerful, and the simplest solution I think all of these layered query generators are trying to do is something simple to write like this.
00:28:03.640
This is just Ruby—the way we would operate on a hash and array. In this case, it looks like an array of, let’s say, OpenStruct objects or person objects.
00:28:20.480
It would be really great if this is how we could write our SQL because, not in all cases, but in some cases, this is really all you need.
00:28:36.680
The username is this, the user login is this, the user password is this. I don't care at all about Active Record's find all conditions or find all by whatever API. I just want to write it in something that’s simple and instantly recognizable.
00:28:51.240
There are many benefits that go with this because there's a very slow learning curve. If this was the API for a number of different ORMs, it would be easy for you to dip your toe into a new one.
00:29:05.120
As soon as you're set up, you can start using it. Whereas now, it's all documented well, but there is a step of learning and reading the cheat sheets, which I personally find tedious.
00:29:20.880
This is, in my mind, the gold standard for simple queries. What's interesting is that this is something other languages already do. If you've ever used Erlang, they have this half cash, half relational database thing called Amnesia.
00:29:35.160
Erlang has built into the language list comprehension. These are not just technical-sounding words but represent backwards enumerable operations.
00:29:56.080
What they do is filter their arrays after the array has been declared in these conditional blocks. It's hard to explain, but once you see it, it makes sense.
00:30:09.240
They run a select and do filtering records through a very terse syntax. Since they already use that for lists, they could leverage that to query their database.
00:30:29.240
We can treat records and tables as lists, and we can write this query in this language we’re all familiar with.
00:30:40.080
What we can do behind the scenes is translate it into a more specific Amnesia query language. The important thing is, we could pull out every single user in the database and run them through this, saying, 'Oh, we’re done here.'
00:30:58.919
But that's not going to work for even small data sets. We need to look at what's going on here and make this into SQL. The way that I solved this problem is with this gem called Ambition.
00:31:16.200
This was kind of just noodling around, learning or laying off of the pragmatic book. They have their list comprehension kind of coding in natural Erlang; Amnesia walks the query language, which I think is a query language for Amnesia.
00:31:41.200
You walk the abstract syntax tree to create the query from that, so the code you write as part of the list comprehension never runs. That's exactly how to do it because that’s what you can do with Parry.
00:31:55.360
This is the Active Record find, a very simple one; it’s a lot of cru because it shouldn’t be an 'all', but there’s a lot going on for something so simple.
00:32:12.040
I want to find John, and it generates the SQL behind the scenes. This, I think, is much clearer to someone doing Ruby; it’s very explicit.
00:32:28.080
What we can do with it is generate a SQL string by giving the User class a bit of magical powers. Here are some of the things that Ambition can currently do.
00:32:48.080
We can do simple selects, passing an arbitrary array. We're asking, 'Is this user’s ID in this array?' This is very Ruby-like; even new Ruby programmers face the enumerable API early on because it’s amazing.
00:33:13.560
This translates to SQL exactly what you would expect. To do that in Active Record, it wouldn't be impossible.
00:33:30.640
You could even say something like 'User.name equals Chris,' but I didn't even want to think about it and write the example slide.
00:33:48.000
This is another example, and it’s also cool because it’s not just select. We want to use detect on top of select.
00:34:06.440
We can say like select.first. Detect has a very specific meaning because it returns nil or returns something.
00:34:23.440
I wanted to detect a user who has an idea titled 'new freezer' whose email matches the regular expression, PJ.
00:34:39.040
This is what that would translate to behind the scenes, with mountains of joins, going across both profiles and ideas, which are Active Record associations.
00:34:56.640
We're using Active Record; we can tell which database we're in, so we can do some database-specific stuff. In SQL, it would look all caps.
00:35:12.760
This is viewed as an expression that’s normal, so it’s cool. Because we call methods normally, it lets us work with Ruby directly.
00:35:24.000
The interesting part is that we're switching and returning correctly at the right time. So, why is this so hard? It’s simple; it's two very simple conditions in a block.
00:35:39.620
So why can't we have a crazy blank slate proxy object to collect what’s going on? After the block has some method called on it, do some issues, but you can’t.
00:35:56.820
There are a couple of things: the first is the double equals operator. If you leave it the way it is, you don’t get the result you expect.
00:36:08.500
That leads to syntax errors and frustrations, dealing with those lower-level commands. However, luckily for us, there is Parry and it lets us get away with the things our mom and dad told us not to do.
00:36:23.440
Like Ruby to Ruby, it’s crazy how simple it is. When you first install it, you take a block and call two S exp on it.
00:36:38.040
You get back this crazy-looking data structure, but luckily it's just a normal Ruby array with normal Ruby symbols and types in it.
00:36:53.280
You’re working with actual Ruby values, as in those are real nil, that’s a real integer one, and those are real symbols. We can focus on the meat and get that implementation detail out of there.
00:37:09.760
This is the parse tree from 1 +1. I'm not an expert on languages or abstract syntax trees, but I've read Wikipedia and been working on this for a while.
00:37:20.640
What this is showing is that Parry hooks into the ABX syntax tree, which Ruby generates when it parses your plain text file.
00:37:32.420
It takes this human-readable Ruby language and builds in memory a semantic representation of what's going on, using different ways to write the same code.
00:37:48.560
Chances are in the abstract syntax tree, they will be represented the same way because it's the same code regardless of whether you use parentheses in an affected spot.
00:38:17.240
This is the Ruby representation of the abstract syntax tree. There's also something called the concrete syntax tree which includes information about the parent; when you deal with grammars directly, there’s one available for Ruby called Treetop.
00:38:43.919
But we don’t care about that at all for what we're doing. Luckily, Parry either doesn’t see it or never sees it. To get a little more academic, this is the classic diagram for what is being represented in a parse tree.
00:39:04.080
It’s 1+1. It’s written in mostly a way representing any standard language. You get this array, and it's always in prefix notation.
00:39:18.160
Elements that go before other elements describe what happens to the nested ones. Here’s the representation, looking at a call that processes this behavior.
00:39:34.440
This is much about how we take a task and how we process it. There are lots of different qualities to handle too.
00:39:48.959
We built a SQL processor, a new class, and set up initializations, thinking back to how we’re handling those structures behind the scenes.
00:40:03.160
So remember that we're focusing on that pattern of the class and how to validate the right pieces for extending their capabilities but have to pass or process our strings.
00:40:18.840
We want to look at the mechanisms of how we get our templates built and understood better. I’ve seen it said that Parry is slow.
00:40:32.040
But you're an idiot and I've run benchmarks to confirm that it is not slow at all. It’s quick because it hooks into information already available. Parry can be used in production with no memory leaks, fast results, and a great experience.
00:41:00.200
You can use it in any situation you want—especially in MERB. In MERB, they have a Parry-dependent mechanism for getting arguments to line up with the parameters.
00:41:16.200
I've seen no problem arise from using the structure itself, and it is a cool gem. As this gem becomes more popular, the community is eager to take on more advanced Ruby features.
00:41:31.760
We can pass in those blocks and manage the translations as needed. However, we also rely on something special—a query object and the ability to build from it.
00:41:52.120
You can code against this class and Ambition will set it up for you. You can define some general command methods to maintain query methods and fire off the right queries when necessary.
00:42:07.360
The exciting part, to many users, is how you can consolidate your requirements and structure everything beautifully. It includes a separate process for any active records generated.
00:42:23.679
You can define the amounts of work needed without worrying how that SQL operates under the hood. That lets anyone understand this more quickly.
00:42:38.960
This library makes code simpler and quicker for many. You can perform fast data manipulation with tasks.
00:42:53.680
The final aspect I'll cover details how the backend helps retrieve your requirements—just to keep things flowing smoothly.
00:43:05.520
If you decide to roll your version of these adapters, you can and it is not too difficult. Simply define the structure and things can grow from your established foundation.
00:43:16.159
This leads us to that second part: Ruby to Ruby does a similar thing. It’s a lot more intense because it understands far more than just select.
00:43:28.480
It calls S exp on the Ruby code, processes the module formats and then spits out the string as needed for your applications.
00:43:41.680
You'll find that it processes robust and standards-based models and highlights distinct frameworks. You’ll also appreciate how it interfaces with regular expressions, something I have had to explore for my own projects.
00:44:04.440
These structures are designed to highlight the series of processes available in programming languages, showcasing their effectiveness.
00:44:16.160
These are just some of the hard capabilities of Parry. Consider the vital integration with JavaScript, C++, and other scripting languages we see in use today.
00:44:29.000
There's no shortage of opportunities here; there are even supporting languages such as Python and Lisp for what these structures can achieve.
00:44:45.080
So there it is, the power of the parse tree and the foundational capabilities of S exp structures. There’s no better time to push the underlying limits—we can process differently-built conditions on data efficiently.
00:45:00.000
This makes for a bright future as we move forward in understanding how to utilize these gems. It opens up our conversation, and I’m looking forward to sharing more with all of you.
00:45:20.720
Thank you for your attention today. I look forward to questions and the ongoing conversations. It’s a collaborative and bright path ahead.
00:45:36.880
Feel free to ask any questions you have. I appreciate the dialogue, and let's propel this conversation together!
00:45:49.480
Yes, thank you! It's great to share ideas. Just a note: make sure everyone in the Ruby community knows that there are limitations in the pars tree.
00:46:02.000
For instance, it does not work and will not work in Ruby 1.9 due to internals not being kept in memory or compiled accurately. It is further challenged in its Ruby 1.9 portrayal.
00:46:45.960
Moreover, other parsers help illustrate the nuances of these processes, ensuring we grow together as a community.
00:46:57.040
Is there anything else before we wrap up?
00:47:05.240
Yes, okay! To clarify, you are able to continue using the parse tree or code that depends on it as long as you’re on Reinius in the future.
00:47:19.560
Yes, that's correct! Thank you again, everyone. Enjoy your day!