We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

My Little C Extension: Lego Robots are Magic

00:00

Formal Metadata

Title
My Little C Extension: Lego Robots are Magic
Title of Series
Number of Parts
65
Author
License
CC Attribution - ShareAlike 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal and non-commercial purpose as long as the work is attributed to the author in the manner specified by the author or licensor and the work or content is shared also in adapted form only under the conditions of this
Identifiers
Publisher
Release Date
Language
Producer

Content Metadata

Subject Area
Genre
Abstract
I didn't know squat about C or building extensions in Ruby. But I did want a Ruby-controlled Lego Mindstorms robot to get kids excited about Ruby. We'll dive into the basics of building C extensions, build a Ruby DSL to teach kids to drive cool Lego robots, and show off the amazing things you can do when you pull up Ruby's floorboards and look at the actually-not-too-scary C code underneath.
39
RobotField extensionAxiom of choiceContinuous trackTrailTrailSheaf (mathematics)Arithmetic meanLecture/Conference
Field extensionRobotGroup actionType theoryCASE <Informatik>Squeeze theoremChecklistLattice (order)Computer animation
CodeRight angleCross section (physics)Computer-assisted translationMachine codeQR codePlotterComputer animation
Computer-assisted translationProcess (computing)Projective planeKummer-TheorieWeb applicationBuildingFood energyClient (computing)Computer animation
Kummer-TheorieVideo gameKummer-TheorieRoboticsCross section (physics)Computer programmingMultiplication signComputer animation
SoftwareComputer programmingInheritance (object-oriented programming)Multiplication signGoodness of fitPoint (geometry)Computer programmingVideo gameMoment (mathematics)CodeBit rateReading (process)Computer animationUML
Computer programmingNumberNeuroinformatikProgrammer (hardware)Standard deviationSoftware testingMachine codeRight angleCodeComputer animation
Computer programmingMachine codeDemonVideoconferencingBitHybrid computerMixed realityComputer animation
DemonProjective planeCodeComputer animationMeeting/Interview
Link (knot theory)Multiplication signGreatest elementOnline helpBarrelled spaceVideo gameRight angleGame theoryComputer animation
DemonDemonResultantCoefficient of determinationConnectivity (graph theory)Key (cryptography)NeuroinformatikRankingComputer animation
Host Identity ProtocolField extensionPoint (geometry)PlanningComputer animationXML
Cheat <Computerspiel>PurchasingQuicksortSoftware frameworkResultantField extensionFilm editingHost Identity ProtocolPattern languageProgramming languageComputer animationMeeting/Interview
Motion blurDevice driverFormal languageEntire functionArithmetic meanNeuroinformatikWordComputer animation
RoboticsTheory of relativityMoving averageMeeting/InterviewComputer animation
Level (video gaming)PlastikkartePiDevice driverWireless LANInformationNeuroinformatikInheritance (object-oriented programming)Computer animation
Type theoryRoboticsInheritance (object-oriented programming)Library (computing)Right angleProgrammer (hardware)Exception handlingGreen's functionComputer animation
FeedbackBEEPProjective planePlanningHost Identity ProtocolMereologyComputer animation
MereologySoftwareCommunications protocolBitComputer animation
Goodness of fitProcess (computing)SoftwareProjective planeChannel capacityMatching (graph theory)WritingVideo gameKummer-TheorieComputer animation
Revision controlBuildingKummer-TheorieError messageConfiguration spaceEmailElectronic program guideProjective planeCollaborationismSuite (music)Kummer-TheorieDevice driverRoboticsMeeting/InterviewComputer animation
Fiber bundleRevision controlInclusion mapComputer fileRobotPhysical systemKummer-TheorieTask (computing)Electronic program guideDialectKummer-TheorieFile systemMereologyCompilerBit rateConfiguration spaceBitLibrary (computing)Device driverComputer fileModal logicHydraulic jumpComputer animation
Physical systemLibrary (computing)Device driverInternetworkingModule (mathematics)MultilaterationNamespaceBitControl flowGroup actionComputer animationMeeting/Interview
CodeWrapper (data mining)Inclusion mapCodeProof theoryGoodness of fitModule (mathematics)Control flowEndliche ModelltheorieParameter (computer programming)Functional (mathematics)DemosceneSystem callMereologyData structureLevel (video gaming)Type theoryGame theoryBit rateRight angleBitHecke operatorMoment (mathematics)Library (computing)Wrapper (data mining)Computer animation
Parameter (computer programming)Fiber bundleObject (grammar)Type theoryProgrammer (hardware)Dynamical systemParameter (computer programming)Wrapper (data mining)Multiplication signKummer-TheorieComputer animation
Personal area networkOrder (biology)Kummer-TheorieMultiplication signPoint (geometry)Library (computing)Type theoryPhysical systemVideo gameTracing (software)Pattern languageExplosionStaff (military)Computer animation
Programmer (hardware)Revision controlCodeTraffic reportingStatement (computer science)Core dumpComputer fileRight angleMoving averageComputer animation
Right angleFunctional (mathematics)Hydraulic motorCodeExecution unitMereologyComputer animationUML
CodeLogical constantOvalAddress spaceDeciphermentSource codeMereologySource codeCASE <Informatik>Library (computing)Monster groupProgramming languageProcess (computing)Sign (mathematics)Scripting languageReal numberPunched cardKummer-TheorieCodeElectronic program guideGrand Unified TheoryExpert systemComputer animation
Field extensionElectronic program guideSparse matrixResultantECosKummer-TheorieElectronic program guideCodeBookmark (World Wide Web)Computer animation
Wrapper (data mining)CodeModule (mathematics)System identificationLevel (video gaming)MP3Active contour modelCASE <Informatik>Greatest elementCodeLetterpress printingComputer animation
Wrapper (data mining)Module (mathematics)Price indexSystem identificationMachine codeNamespaceSpacetimeLibrary (computing)Module (mathematics)Endliche ModelltheorieType theoryComputer animation
Data typePrice indexInterior (topology)Type theoryNamespaceParameter (computer programming)Wrapper (data mining)Rule of inferenceModule (mathematics)Key (cryptography)Point (geometry)Multiplication signComputer animation
Address spaceData typeModule (mathematics)UltrasoundProbability density functionPrinciple of relativityPoint (geometry)Type theoryModule (mathematics)SurfaceLogical constantCuboidComputer animation
Cheat <Computerspiel>Planning2 (number)Arithmetic progressionHand fanRevision controlMetropolitan area networkGodComputer animation
Cheat <Computerspiel>Video gameCheat <Computerspiel>GodMetropolitan area networkTwitterWave packetRight angleVideo gameComputer animation
InformationKummer-TheorieCheat <Computerspiel>InformationOnline helpForm (programming)Bookmark (World Wide Web)Point (geometry)Kummer-TheorieModule (mathematics)Black boxComputer animation
Wechselseitige InformationMereologyUsabilityNP-hardPlanningHydraulic motorComputer animation
Blu-ray DiscCodeSoftwareSoftwareReal numberAbstractionRight angleProgrammer (hardware)CodeLibrary (computing)Computer animation
CodeCodeState of matterLibrary (computing)Cheat <Computerspiel>Process (computing)RoboticsSoftware testingImperative programmingRight angleBit rateWordTerm (mathematics)Computer animation
Term (mathematics)WhiteboardDialectReal numberVideo gameCheat <Computerspiel>Revision controlRemote administrationHost Identity ProtocolUML
Category of beingScalable Coherent InterfaceDistanceRoboticsPlanningCheat <Computerspiel>FeedbackoutputProjective planeSoftware testingArithmetic progressionCASE <Informatik>PressureLibrary (computing)CuboidRevision controlProcess (computing)Dynamical systemRule of inferenceAnalogyComputer animation
Cartesian coordinate systemBuildingBlock (periodic table)RoboticsSheaf (mathematics)
RoboticsBuildingGame controllerWordWebsiteCode
Square numberQuicksortRoboticsCodeBridging (networking)Mögliche-Welten-SemantikComputer animation
Open sourceSoftwarePoint (geometry)Condition numberLibrary (computing)Form (programming)Digital electronicsProjective planeInternet forumSession Initiation ProtocolSoftware maintenanceLattice (order)Computer animation
Projective planeCycle (graph theory)Digital electronicsImage resolutionGoodness of fitWell-formed formulaOnline helpMeeting/InterviewComputer animation
Firewall (computing)Kummer-TheorieComputer programmingKummer-TheorieComputer programmingOnline helpPressureQuicksortComputer animation
Cheat <Computerspiel>PurchasingVector potentialConstructor (object-oriented programming)QuicksortComputer programmingVector potentialPhase transitionComputer animation
NeuroinformatikProjective planePressureBitPoint (geometry)SpacetimeKey (cryptography)Computer animation
InternetworkingComputer programmingCodeVideo gameProcess (computing)Level (video gaming)MathematicsSoftware developerElectronic program guideJava appletComputer animation
Electric generatorRevision controlPower (physics)Demo (music)Computer animation
CodeNeuroinformatikHazard (2005 film)UML
Execution unitWindowTwin primeVirtual machineComputerComputer animation
Physical lawMultiplication signComputer programmingDemo (music)Shared memoryGame controllerCodeGastropod shellLie groupRight angleTurtle graphicsPhysicalismFormal grammarTask (computing)Software testingInheritance (object-oriented programming)Control flowExistential quantificationBinary fileComputer animation
SoftwareEvent horizonVideoconferencingComputer animation
Transcript: English(auto-generated)
I think this is probably a good place to start.
Hi, welcome to FringeRuby. I don't even know what that means. But I assume it's like Ruby but fancier. So welcome to FancyRuby everybody. I'm Brandon, I'll be your host for this section of the track. And also a speak guy. So thanks for choosing whatever this is.
You don't know what it is. But the talk is called this, so you know that much right now, right? So thanks for letting me talk to y'all. In case you were wondering, I'm not actually technically a brony. There's some checklist I'm sure I fail. But I do have a favorite My Little Pony character. That's definitely Cheese Sandwich.
If we have any other brony types in the house, don't raise your hand. Meet me in the anonymous group afterwards. We'll get something going and names will not be revealed. Before I start, just a quick story. I came home recently to find this in my driveway.
Which, you know, people don't necessarily park in my driveway that aren't me. So I investigated and I took notice of a couple of things here. This... I'm sorry, what? This can't be real, right? It's like a meet-cute plot from a Tom Hanks, Meg Ryan movie. I kept waiting for them to bump into each other.
And also, that's a QR code for this cat sultan. For whatever cross-section of the population is looking for a cat sultan and uses QR codes. Which is actually probably pretty high. But it is real. There was some cat emergency near my home that necessitated parking in my driveway.
And then I realized, oh my gosh, this is awesome. Somebody's job is to be Ghostbusters for cats. So that's when I realized what I'm going to do with the rest of my day is I'm a cat sultan. I work at the front side. It's frontside.io. We build client-side web applications primarily using Ember.js.
So I'm hoping this talk about RubyC extensions convinces all of you to want to work with us on your Ember projects. And now you can see why I flunked out of my marketing career. So why is some lapsed Rubyist up here occupying the next 45 minutes of your life? To talk about C extensions, obviously. Who isn't excited about C extensions?
About robots? That could be kind of fun. About ponies? For some cross-section of the population, ponies are awesome. You can accurately predict the sprinkling of those. As much as I love all of those things, well, maybe not C extensions, but as much as I love these things, this talk is actually more about burnout.
My burnout. It's a little personal. But it might reflect some experiences that you have had or have yet to have. So see if any of this sounds familiar. About five years ago, I started learning to program. I was marketing and wasn't having a super good time at it, clearly. And I discovered programming. Somebody introduced me, handed me Chris Pine's Learn to Program book, and I lit on fire.
He said, you'll know in two weeks whether you like programming or not. And I knew in two hours. I came in the next day, I was like, you guys get paid to do this. And he said, yeah, it's pretty crazy, right? So from that point forward, every spare moment of my life was spent practicing learning to program. And every book I read was programming.
Suddenly it was my new hobby. And then that magical day came where I was suddenly paid to code. And it was now my new career. Like, what in the world is better than getting paid to do this all day? It's crazy. And then I noticed, like, it took a number of years, but, and all this wonderful things started happening to me.
Now I get to run a company with some of my closest friends. Like, I'm basically living the dream, as far as I'd seen five years ago. But I noticed some of my passions start to wane. And I wasn't sure if I 100% love programming anymore. Like, had I fallen into the wrong career? Was it supposed to have just stayed a hobby? So I turned to the Church of Computerology.
They gave me a programmer audit. They told me that I had less than 100% test coverage. My code was not clean and not professional. It was not precision-crafted to the standards written in the high holy documents of things that I will not name here. But I could buy these books and methodologies to fix my code, right? It's not about fun. It's about professionalism.
Instead, I just kind of fretted. And I practiced creative avoidance. I worried I'd lost any ability I ever had if I actually had ever gained any. Maybe my taste for coding was just gone and my career is over. Like, thanks, programming. See ya. I guess it's over. It was pretty cool.
But the thing is, I fear these things about myself. But I don't actually believe them. I can look at empirical evidence and realize that this is only temporary, even if it does suck. So let's look at it a little bit. What was wrong with me? Maybe I pushed too hard for too long. Maybe I was working on the wrong stuff. But likely it was just the career bit of programming, which I think all of us do.
We have this career-like hobby mix, hybrid, that's pretty rare. And it started to press down on me. And I became too exhausted to fight off the demons that tell me I can't do stuff. So what can we do? How do we fight these demons? I'll tell you what I typically do. When I get burnout, I try to rub some work on it and see if that works.
Just more work. Just lean into that. I was never accused of being a workaholic before starting to learn to program. But I definitely am accused of that now. And it's doubly true in trying to run a business. So for some reason, though, rubbing more work on your burnout doesn't really work. It does actually alleviate the symptoms for a little while. But it delays and then magnifies these costs.
So all right, what about cool distractions like jumping into VR with Murder, She Ripped? I seized up. Seeing code gave me some anxiety. And I couldn't work even on the side projects I was excited about previously. So distracting myself became an outlet for me. So I started consuming rather than creating things.
So let's examine the value of these with this highly scientific chart. It's calculated to the exact return on investment of my various distractions. So West Wing was a really great use of my time. I learned stuff about American history, got all excited about it. And then Link Between Worlds, that's a fun game, right? And then start getting the dicey TV dramas, comedies? I don't know.
And then you start scraping the bottom of the barrel when you're just looking at human suffering for distraction. Yeah, well that guy's life sucked worse than mine. That's helpful. Thanks. But that doesn't help. It just kind of defers the costs again. And there's nothing wrong with any of this.
It's just it doesn't work. So we've tried ignoring the demons. We've tried drowning them out. So how do we actually silence them? This is what I've learned. The answer is really simple and really difficult. Especially when you feel like you have to work or those demon dogs are going to catch up with you. But the thing is, you have to stop and play and then ship the results of your play.
The most crucial component is actually shipping it. So I did learn one weird trick from the computerology thought leaders. And it appears it's like a key to basking in the glow of their ranks. If you coin an acronym, you are going to have the coolest stuff happen to you. You're going to get book deals and conference keynotes, if it's a good one.
So I hope we've got a good one here. It's Hips Cafe. The secret to overcoming burnout is all outlined in my Hips Cafe plan, book deal forthcoming. I assume somebody's going to walk up to me after. You're probably asking yourself at this point, was this not a C Extension talk? So just hear me out for like two more minutes.
So Hips Cafe, let's throw a mnemonic device on top of a mnemonic device and say, think of like an Elvis themed diner. Except all diners are already Elvis themed. So here it is. The secret is to actually play until you ship. And this is sort of a framework to play in a way that results in shipping. So we're going to build our, if you look at steel knowledge, we're going to primarily build our C Extension in there.
So if you're like waiting, you're like three letters away. So the first one is to hit burnout. We've already talked about this, but to acknowledge it is a really important step. And if you don't feel it, great. The trick is, you have to say it, I'm burned out, and stop. Cut it out.
Alright, the second step is pretty organic. Something is going to catch your eye or your fancy. For some it's finding a book about a new programming language. For other people it's like a magazine of knitting patterns. It's anything that inspires you to want to make something. For me, it was finding these Lego Mindstorms. More specifically, it was a Kickstarter to control them with a Raspberry Pi.
I love Legos, my kid loves Legos. It seemed like just enough DIY to get me interested in building something, but still easy enough that I'm not writing C-level drivers, which I couldn't do in a billion years. So it's built on the Raspberry Pi, which is simple and cheap and amazing. It's surprising to me how much the Raspberry Pi has actually come up in this conference.
It's got an entire computer on board, meaning that bring your own language is actually possible. And somebody else is writing those drivers, which is awesome, because they're probably smarter than me at it. And also, I don't want to offend anybody if you work for Lego Mindstorms, but your brains are stupid, and people should take them and throw them in the garbage. Because now you can take that and throw it away and let people like Matz and like Linus write the brains that will run your Lego Mindstorms.
And let me tell you what my dream is. You guys are going to think it's stupid. But my dream is that I want a robot to solve all of my ketchup-related problems. Or like deliver tacos, or like draw pictures or something.
I want a robot to do something, right? So now the next thing that comes along is you can actually play with stuff now. Unlike a lot of Kickstarters, this one actually shipped, and we have this cool shiny toy to play with. So what do we do with it? Well, you can SSH into the Raspberry Pi and talk to it.
And then I went down this crazy rabbit hole of SD card cloning. If you've ever tried to do that, it takes like two hours, and wireless drivers. And the thing is, I was burned out, but it was a super fun experience to try to figure all that stuff out. Because yak shaving can actually be fun if it's your toy pet yak, and nobody's sitting there tapping their watch waiting for their yak hair. So all the info for all this stuff is online, and eventually you have a computer that works.
All right, now it includes a simple C library with examples to make the robot do some stuff. So I'm not, as you can probably guess, I'm not like a super C type person, but this is for fun, right? So we crack our knuckles and we get started. So let's write it, all right. The library is really ugly, but it's usable. It's arcane, kind of yucky, but we can copy, paste, ship it.
We're programmers, that's what we do. So I got this Hello World and got the motor suspend. And that was a very exciting moment, except for the fact that I had then run out of ideas of what to do with this thing. Because I'm not sure how to make it do anything more than that. All my robot catch-up dreams were suddenly like super far away. Because do you know what writing stuff in C feels like?
Many of you do. You know that it feels like this. It's like trying to swim with a straightjacket on. It's not super fun to extend. It's pretty painful to recompile, and there's a really crummy feedback loop. And then you realize like, dude, I know how to drive an F1 car. I have it sitting here.
And instead you're like sitting in this little Shriner mobile, like beep, beep. And I could be using Ruby with this. So congratulations. In your side project that you're doing, you're now officially and thoroughly stuck. It's bigger than your playtime ambitions. Shipping is going to require a little or a lot more from you than you know now. But you don't fret about it because that's where the Hips Cafe plan comes in.
So part S, steal knowledge. That's the next step. You need to find somebody to help unstick you. It's helpful to find somebody who's excited by the same kind of things that you are. And some people might call this mentorship. And I wanted to drop a quick note about mentorship. If you are relatively new, you're going to have to build your own mentorship.
You've probably heard this already. And it's really challenging because you're like, will you be my mentor? Will you be my mentor? And you ask a bunch of people and they say no. But Ruby is one of the nicest communities in software. And you are going to find mentors here. And if somebody wants to help you but can't, you can ask them who they can ask. Because you know somebody who knows somebody.
And a cool way, pro tip, a cool way to trick somebody in a mentorship is just to be like, hey, can you come over here and look at this for a second? Just for like a second. And then you draw them in for three months. It's amazing. It's worked for me. It's how I learned Ember. It's amazing. So if you're more experienced, you need to learn to open yourself up a little bit. A lot of newbies don't realize that you're actually waiting for an opportunity to help out.
And if you are experienced and at capacity, it probably means you have a pretty good network of people and you know somebody who can help out. So your job then is to delegate and matchmake. All right. So for me, I'm lucky enough to work with one of my mentors. Charles Little created a project called the Ruby Racer as a hobby toy thing.
And then it kind of got accidentally wrapped up into Rails, and now he does support for that for most of his life, and it sucks. But it also is a C extension, and it's one of several that he's written. So to say that he made this possible would be a pretty vast understatement. He's my advisor and helper and collaborator and then took over the project and tried to write a C.
Anyway, he was definitely my guide to this stuff, and I learned a ton from him, and I appreciate it. And he had to take into account that my prior experience with C extensions was just watching them explode helplessly. If you've ever done this, you know what I'm talking about. And so he knew that I was starting from zero, and I want to share a few things that I learned.
Keeping in mind that my goal here is to make a robot do stuff with Ruby, and the drivers are in C, and we know Ruby can make C dance. So I grit my teeth, and I charge in fearlessly right after Charles. So step one, you need to have a gem to work from. The guides on this are very, very good. I don't need to belabor it. I've never built a gem before this, and now it's desperately easy.
I could see why it would be very tempting to release a million gems, but I don't, because I don't know. I'm not one of the gem people. But step two is to lay a groundwork for the file system. And again, there is C extension documentation on the Ruby gems guides, and it's really well done. I think this is one of the nicer parts of the Ruby community, is they usually care a lot about documentation.
So you have some necessary files and folders. You tell rate compiler how to build it. You add a tiny bit of config to your gemspec, and then you have a little more standard stuff. There is one trick here that is to require the drivers that come with the brickpy. And that is find wiringpy here, where you see that find library wiringpy.
Make sure that it has serial open method in it. And then Ruby will handle the compile step for you from here on out. So the next step is to specify the API we want, because to paraphrase this TV preacher guy or whatever, we go to war with the API we wish we had, not the API we have.
So this isn't pretty, and we will get into why later. This is intentionally not pretty. But suffice it to say, this is the API that we want. We have this brickpy native module under that, and brickpy setup. And the question is, how do we reach in to the C to actually execute brickpy setup from Ruby? So this should, we'll dive in a little bit and break it apart.
This should look pretty familiar to Rubyists. We specify the top namespace, the native namespace, and the setup method. And again, we'll explain why this looks a little weird later. But our goal is just to get to status code 0. We want to start with a very small proof of concept that executes that init function, and returns that status code 0.
Right now it retries, if you do anything, it returns status code 1, because it doesn't work. So that's this bit of code right here. It doesn't look like much code, but there's a lot to unpack. So we call setup, which should return status code 0. The first thing we do is we include the dependencies. So we include rubies, ruby.hclibraries, which is how Ruby talks to C, and it's really handy.
If you ever actually crack open ruby.h, just for fun, I don't know, get a beer or whatever, look at ruby.h, there actually is lots of cool stuff in there. And then we include our C dependencies, and I'll show you how I realized I needed those in a moment. The only thing to know about this init method is it's magic and it bootstraps our code.
We define a top-level module and a native module underneath it. So we're defining these Ruby things in C. Then we define our method on the native module, named brickpy setup to match the C method. This is for convention. It's not required that we call it brickpy setup necessarily, but we do.
What this does is this calls a C function named call brickpy setup with no arguments, and then we write the actual wrapper method. It calls the original C function, the brickpy setup. This is the one that was actually part of the library that came with the library. We execute that and return that, but we first have to cast the C types back to Ruby types to send it to magic, happy, wonderful Ruby land where everybody hugs each other,
instead of C, which is like Hunger Games basically. So we just said zero Ruby arguments, right? But what the heck is this? It actually means zero Ruby arguments. The first argument in any C wrapper is a magic value self thing. And to explain that, we'll have to delve into some really kind of yucky stuff.
If Dr. Moreau were a programmer, he would probably have come up with some half object oriented half C monstrosity, some abomination like C++ or Objective-C, and there's no evil science here. All value is is it's a little magic thing that says this is just passing through. It's a Ruby type. It throws its elbows around to allow Ruby's dynamic types to pass through.
So sure, there are zero Ruby arguments, but the first argument of any Ruby wrapper is to pass the Ruby object in. So then we just build the gem and try it out. Obviously it's going to work the first time. What happens next may surprise you. So this lady is experimenting with cooking without nonstick pans you order on TV.
Just like we're experimenting with building a C extension. This is going to blow up a few times for you while you work out the dependencies. This is how I found out that I needed that tick.h library, by the way. It's going to look a little more like this, but it is going to feel like a nuclear explosion in your life.
And segfaults are suddenly your own fault. Welcome to the world of creating segfaults on your system. For me, at one point I passed the wrong types to an array lookup. The stack traces these days though are really helpful, and they actually helped me dig my way out. And you get into this cool little pattern of build, run, explode.
Build, run, explode. Explode, explode, explode. And then suddenly, we have the API we asked for. So I think we should have the Ruby core team bake personal affirmations, actually, into the IRB return statements. I feel like that would really help me a lot in my daily mental struggles.
So our Ruby file is actually empty though, right? We're using Ruby, but we haven't written any Ruby yet. Except we have. Whoa, mind blown, right? So where is it? It's here. Remember this? We were just writing Ruby. We're just doing it in C. So wait, you can do that? Yes, of course. How do you think Matz writes Ruby?
How do you think Ruby writes Ruby? What do you think it looks like when you open the hood? It looks like that. It's just calling those literal exact same functions we were using from Ruby.h. And to me, that was a revelation. To many of you, you guys are like, obviously, dummy. But for me, it was a total revelation. And getting from status code 1 to status code 0 was actually the hardest part.
So now you've got some of that C code wrapped. It's compiling, it's returning a good status from the init method, and Ruby and C are talking to each other. So the rest is just fleshing out the API and getting that wrapped and getting those motors to spin. So part 1 is wrapping the rest of the API that we need. So how do you know? How do you know what to go wrap?
Where do you start? That can be very confusing, except we have some documentation in source code. If you don't have documentation or examples, I don't know what to tell you. I'm sorry that you have a C library with people that are just hateful monsters. But in our case, we have API examples. So wrapping the code makes us a consumer of this public API.
So let's consume it. We know Ruby in JavaScript. At least I know Ruby in JavaScript, and so when I squint at this, it almost looks like a real programming language. It's a little verbose. A lot of C people in here are going to come punch me in the gut at the end of this. It's going to be great. There's a lot of setup in here. And the API docs show us what we need to wrap. The source tell us how to wrap it.
So it's a little verbose, but we have to resist the temptation to try to clean it up for now. So now I'm going to stand before you as an expert in the subject, obviously, and give you a C extension style guide. The C code here is pretty hideous, and C extensions are a wild west. So the idea of a style guide is kind of ludicrous. But the result is building a C extension in a way that you can kind of set and forget.
If you do these things, this is really some hard-won knowledge. How do we get the know-how to do this? Documentation for this is kind of sparse, not super-current. It's not something that people do a ton. And it's true that hard-won knowledge is usually the best knowledge. My favorite is when hard-won knowledge is stolen from somebody else who won it. Like this. If you haven't read this book, it's fantastic.
So all of these things are hard-won knowledge by me. I'm totally lying. This is hard-won knowledge by Charles. And I stole it. And that's what's so great about mentorship. It's knowledge theft. It's legalized knowledge theft. It's like downloading MP3s of understanding from people.
I'm trying to pitch this in a way that people will want to do. So these three things, we'll talk about them individually. The first one is to keep the low-level Ruby really ugly, as close visually to the C as you can. The contours of this Ruby API should mirror the C API very closely, right down to camel casing and parens.
When you get to the bottom of your Ruby API, it should be obvious that the next step down is your C code. And everything starts at the gem namespace by convention when you're working in a Ruby gem. So a subnamespace of native is a great way to sandbox all of this native code. And then we can add more namespaces as needed. Again, everything is namespaced under this brickpy thing by convention.
And the C struct in this library does a lot of heavy lifting and namespacing. So we're going to mirror the C struct namespacing with modules in Ruby. And these are just helper methods to wrap and call C methods. The next thing is to prefix these C method helpers so we can find which one are actually helpers. They call up, and then they actually call the underlying C from the brickpy library.
This is modeled after the rb underscore methods that come in Ruby.h. So now we can kind of pull all these things together into one thing. We'll tackle something that's a little more complex, an array setter. So first we'll define a namespace module for sensor type under native which mirrors the brickpy dot sensor type namespace in the C struct.
We're just C struct over to module namespace. We create the Ruby method to set an array element. And we call up to the prefix wrapper. And then we pass self first, like we talked about. I don't make the rules here. I just obey them. And just like if you were defining in Ruby, it takes a key and a value argument.
And they're prefixed with values. Because again, everything that's a Ruby value is value. And these come in as Ruby types, so we have to cast them into C types. And this is the actual C work that's being done. We just set the value on the array. I don't really know C, but I can read this. And then Ruby expects the set value to be returned.
Again, I don't make Ruby rules. I just know if you break them, it blows your face inside out. So let's not break Ruby. And then from that point forward, this is going to sound dumb, but it's literally the same action over and over again. We're only wrapping a few types, so we just need to finish the rest. So if this looks kind of repetitive, modules, submodules, singleton method, array getters, array setters, and a whole bunch of constants.
This repetition is really good because it means we're pushing all of that C API out to the surface so that the Ruby API can hook into it. And we never have to look at the C again. We can stuff the C inside a box, inside another box, in a vault, and hide it in a volcano. So, hang on a second.
How do I know all this stuff? It looks super arcane. Obviously, I don't. Clearly, if you haven't been paying attention, I don't know any of this stuff. But I did learn a lot of it by cheating. And I believe in cheating to win. That's the next step in the Hips Cafe plan. Yay! So now we're in the cheat to win portion. Actually, as a little side note, I have this thing.
I have this dream of an alternate. It's a fan screenplay. I haven't published it yet. But it's an alternate version where they train Johnny to be the best cheater in karate. And it's got an 80s montage song. It's a work in progress, but it goes like, Cheat to win, gonna have to cheat, working hard for chumps.
And that's all I got. Just spitballing here. But if you don't believe me, I actually sing that at work. But I believe in cheating to win. I believe it was the great philosopher C. Montgomery Burns who said that, Why should the race always be to the swift or the jumbled to the quick-witted?
Should they be allowed to win merely because of the gifts God gave them? Well, I say cheating is the gift man gives himself. So it probably would be helpful to define my definition of cheating. A lot of people call this stuff life hacks, but I think cheating sounds cooler. It apparently gets more Twitter followers from life cheats or whatever. And this cheat right here to reheat pizza is awesome.
Download the slides and use this and you'll have better pizza. And stealing knowledge is often called this. Like we call cheat sheets thing. It's accepted and even encouraged way of sharing information. It moves humanity forward. When people say they're standing on the shoulders of giants, that's a really nice way to say that you're cheating. My favorite form of cheating is to enlist the help of really smart friends.
Alright, so at this point and this knowledge and a lot of cheating, wrapping the C extension was relatively easy. The native module is inside a black box and we shouldn't need to touch it anymore. So let us never speak of it again. So the hard part, surprisingly, is getting the Ruby API usable. Because it does function, right?
This looks and works almost exactly like the original C, only it's in Ruby. That's actually good. That's part of the plan. But it's not for human consumption. If we do use it, something amazing happens. Charles and I were at RailsConf this year and we were like, we got the motors to spin. I don't know how to explain it, but this stupid little thing, we entered a value and a motor started spinning
and it felt like we were the champions of Earth. And it was great. So the question is, okay, well, are we done here? Incidentally, Taco Cat is a palindrome. So introducing our first real Ruby layer of abstraction. Let there be no doubt, though, this is terrible software.
I want to tell you something, though, a secret that I've been keeping. I have a passion for writing terrible software. I saw somebody else had a bio that they submitted to the conference and said they had a passion for writing well-crafted software. I don't. I have a passion for writing terrible, terrible software. But the thing is, I kind of hope you do, too. Because if you don't, how do you start anything with this paralysis,
this fear of imperfection? And for me, it was really hard. I actually had to earn my pride in crap. I had to earn it. Because my fear of imperfection prevented me from doing anything. And overcoming it was a big obstacle in learning to be a programmer that can tackle hard problems without being afraid of it not being perfect.
I do love writing terrible code. And I love to ship. But I don't love shipping my terrible code. And this library is not actually releasable in its current state. But we're cheat commandos, right? So we're going to cheat to win some more. All right, cheat. You can look at this, and you can see some cheating, but it's not as bad.
There are no tests. Sure, it's quick and dirty. But it does provide a nice usable API. It's imperative. It's kind of inflexible. But for some value of robot, it gets the job done. Slap a label on it, tag, ship it. And one cool thing about this in terms of cheating, if there were no such thing as miracles, first off, how would you explain how the boards got on this rock?
Also, how would you explain rake release? Rake release is a miracle. One-step gem deploys, right? You can't explain this stuff. All right, so after installing the real-life gem on the Raspberry Pi from RubyGens, I was able to wire up a remote control in 45 minutes of just hacking around on stuff.
And for me, that was a successful consumption of the first version of this API. But we're not done yet, because the next step in Hips Cafe is you have to atone for your cheating. You basically incurred some technical debt, and you're not done until you pay some of that down. You can put yourself on a plan or whatever. You don't have to pay it all at once in a balloon payment or whatever. The cheating does catch up with you pretty quickly, though.
It's hard to get the robot to do anything more than these very simple commands. And we added some stuff that we wanted it to do. So let's see what we can do to improve it. There's still no tests here, but it's a little more capable as a robotics library. It accommodates more use cases. We're working on the niceness now of the API. This version was inspired by dynamic JavaScript libraries like Ember and React.
It can do multiple things at once, so you can kind of layer behaviors on top of each other, handle rules, it handles things like analog input, incorporating feedback from sensors, and it works very nearly. I mean, it's so close to working. But obviously it's still a work in progress, but it's fun to work on this API.
This is still, like, this project, we've kind of gotten pretty deep into it. But because we took one of the hard things and put it in a box, and now we're kind of riffing on it, we're like, oh, do we like this API? And there's no pressure around it. Suddenly this is, like, a really fun project. So the next step is to find a practical application. So you've done all this stuff just to kind of, like, we were out in the lobby building Legos.
And what my style of building is to say, oh, I'm going to put these pieces together in a way that I find visually interesting until I have something that feels like it might be something and then try to turn it into something, like, oh, this looks like, now it's a fountain, it looks like a skyscraper, it looks like something. And then you kind of repurpose this thing that you built.
So suddenly we had this thing that was purely a distraction. This had no value to humanity whatsoever. But what if we start to see what it can do? Well, it's a flippin' robot made out of building blocks, so it can do all kinds of crazy stuff. But one thing stuck out as I started playing with it. I handed the controller to my kid, and I saw him start to do this.
And I was like, wait, what? And he started getting really excited about Lego and robots. And a particularly insightful friend told me that I seem to have the most fun when I'm teaching others. And this was my toy. Give me that. But my kid getting psyched made me wonder, what if this could possibly be something that gets kids excited about code?
So what if kids could program a simple, logo-like syntax and draw cool pictures? It's not perfect, but it's sort of interesting. And my kid thinks it's super awesome. I'm still improving this, obviously, but I'm proud of the little guy. And I take these pictures, and I put them up on my super giant fridge.
And it might not sound like the most practical use for robots, but I'm excited and inspired by seeing people do art with code. And now, suddenly, it feels like a world of endless possibilities. All right, the last step is to reward yourself for shipping. The philosopher Neugeck says that we are conditioned by Coke's marketing to believe that Coca-Cola is a reward.
Do you know what I say about that? He is right. It's delicious, ice-cold, refreshing conditioning. I think, at this point, you can relax on the beach, sip a Coke, and let your book deals and thought leader checks roll in. I'm guessing this is how this works, other open-source maintainers. Meet me afterward and tell me where I, like, submit the forum to get my thought leader checks.
You guys will back me up. So there's only one hitch, is suddenly there are a few people downloading this and saying, hey, I use your library now. And I know all the horrible secrets of my software, and I know that other people are going to bump into them. And now your fun toy project is its own kind of work.
You've completed this circuit. You've, like, ride your burnout resolution all the way back into burnout. So I don't have a good answer for that. I hope it's a virtuous cycle. You get to meet interesting people, and hopefully you can delegate to them. And a quick confession, like, as I stand before you today, I am as burned out a person as I know. But that's my secret. I'm always burned out.
I haven't got it all figured out. I felt like a total hypocrite giving this talk to everybody and saying, hey, I found, like, a formula to help you with burnout, and I'm still super burned out. And I know what the answer is. I'm just not that good at executing on it. But I can say that even though I'm constantly teetering on the edge of burnout, this helped a lot.
So how did this activity help? How did it work that I was super burned out from programming, but I managed to pour dozens of hours into learning C extensions? And then how did it actually help alleviate and fix it for a while, anyway? It did, though. Here's the thing. I think sometimes we put so much pressure on ourselves to make things for other people that we forget to make them for ourselves.
How this thing, you know, this is sort of a silly construct. But there is some truth to this in the idea of playing until you shit. Burnout, I believe, happens because you forget that you love something about this.
I think playing is how you get back into the courtship phase. It's like a date night for your love of programming. And I don't think it's a coincidence that children live in a world of endless possibilities and in a world of play. And in a world of unlimited potential. They have infinite opportunity.
So look at this guy. He's not bright. Look at him. He's a dummy. But he's getting smarter. And how fun is it to participate in something like that? I believe that it's really important to note that sharing play projects, if you look back at the history of computing, is the source of much of the advances that have been made.
I don't think people should put that pressure on themselves. The idea is to play. But each of us has something that we like to play with and are passionate about, but maybe we're a little afraid to ship it. And I think shipping is really key. An example would be Jen Schiffer shipped her Make 8-Bit Art and now VAR Institute project. The whole point of these things is to have fun and make things. But they're also making people think.
Edna Piranha shipped Meetspaces, which is a totally different and novel way of interacting with people on the internet. A personal story, I thought programming was shut out to people like me. I really thought it was for math majors and stuff like that. And I didn't understand why yet, but somebody handed me Wise Poignant Guide to Ruby. And I did not understand one code in there. I think it was written for Java developers or something.
But it did tell me that programming was an intensely creative and artistic pursuit, if you want it to be. It is not an exaggeration to say that Wye changed my life by shipping his art. The world needs your work. It needs the not-burnt-out version of you. And it needs you to share what you've learned.
I believe that play is the only power fun enough to inspire the next generation. So go try something great, get stuck, and you'll be surprised who shows up to help. So I want to show you guys a demo of this guy, and it may or may not work at all. So there are no guarantees here, but we have an extra minute, so I want to do that.
All right. I want to show you what I'm doing, but the problem is I can't see what I'm doing if I'm over there. So I will do it, and then I will show you. Okay.
So what I do is I load up a marker in my very scientifically developed and not haphazard at all marker container thing. And we will see what happens with this code.
Sorry that the Raspberry Pi is not the fastest computer on the planet, and it's not pulling up that code.
All right. So this is the code, and this is, again, the world's fastest computing machine.
All right. Let's see what happens. Maybe nothing? Maybe something? Maybe nothing? Well, let me bring this over and put Ruby on it. That shouldn't be a problem.
That was the wrong window, wasn't it? It's my first day. You've got to do bin bash login, obviously, because you don't have bash. Bash is a, I would call it a shell for chumps, is probably what it stands for.
Turtle test. Let's try it. Yay! All right, woo!
So it's just a logo-like syntax, right? Where if you, while it does that forever, let me try to pull that code up again. It won't do that forever. It doesn't have the batteries for that.
Come on, you guys. Don't you know anything about physics? You'll fall for anything. All right. So I can see over here, so there's some setup code, and then there's the actual, I can't see it, but I assume.
Yeah, so see that 12 times do? That's about as simple as code can get, right? So you can teach kids this kind of code, and my kid really digs it. It makes them excited to program. There's another thing that you can do with it. There's another demo that I'll do that is not as exciting, but it's kind of cool.
My Bluetooth controller will turn on. Yay, live demos, wee!
So my kid can grab this controller and just drive a little robot around and break it, which is great. That's his favorite thing to do, actually.
And then it also handles behaviors, and I want to show you that really fast. So it can handle multiple behaviors. So it does one thing if the sensor doesn't detect something, but if it detects that something's in the way, it will turn out of the way, which is pretty fun, I feel, which is braggable.
So it's a dummy, but it's really fun to play with, and anybody can do this. Like, literally, if I can do this, anybody can do this. And programming is super fun, and it's something that I hope you guys are inspired to do to share something with other people and get them excited about programming as well.
I think that the future of programming depends on it. I actually think it's really important, and thank you very much. Go out and make something fun for everybody.