Showing posts with label Ruby. Show all posts
Showing posts with label Ruby. Show all posts

Thursday, January 26, 2012

Using Twitter Bootstrap to Render Partials with Tabs

It's been a good week for coding. I've done some pair programming, interviewed at iGoDigital, and dug into Twitter Bootstrap.

Which is actually the topic of this post! WEIRD!

Anyone ever tried using those sexy little tabs to render partials? Basically I'm working on Chorenivore again, and I want a tabbed view of the days of the week, with each tab containing items that are supposed to be done that day. I'm currently thinking of a separate partial for each day, though this could probably be reduced to one partial that simply renders each chore that's been tagged with the day of the week, but I thought I'd make it stupid before I made it clean.

Here's the specific code I'm talking about:

Twitter Bootstrap Tabs

I understand how to switch through actual links just fine using these tabs, but how would you do the same thing with partials? I found this question on StackOverflow that seems to address this, but I couldn't get his example to work.

Here's a link to Chorenivore on Git:

Chorenivore on GitHub

A couple other things. First off, I haven't really used Rails in the last four or five months and it feels so BULKY compared to Sinatra. I'm all "WTF, how do I link to a new view and actually make it do right?"

And does anyone know where I'd find Why's Poignant Guide to Ruby? I feel a book report coming on.

Tuesday, January 24, 2012

Resurrecting an old project

Have you ever been thinking so hard about a problem that you don't even notice when the music you're listening to has stopped playing? This just happened to me about five minutes ago, while I was looking through the code for my old project Chorenivore.

I'm thinking about getting back to work on it for a couple of reasons. Working on a more concrete app that does a few very specific things is both more useful and easier to do than spending my time coding a game, like Dungeon Crawler. I've tried to find a good to-do application, but haven't had any luck. I've tried Tadalist, ToodleDo and Remember the Milk.

And it's a good idea to work on a project to solve a problem I have.

Problem? I don't like the to-do applications I've tried.
Solution? Make one yourself, dummy!

What I want Chorenivore to be is a simple to-do application that allows users to create single and repeating tasks. I also want users to determine when a task should be completed upon creation.

Then I want a list of the days of the week, which allows users to drill down and see what's due that day. I may want some other visual cues in the future (such as showing how many tasks are due on a particular day, or separating single and repeating tasks) but for now I'll be satisfied with tabs that render partials for each day of the week.

The real thing I think is missing from online to-do lists is the satisfaction of crossing an item off a list. I often find myself making lists simply so I CAN check things off of that list. I'm sure I'm not the only one, so I'm thinking about ways to replicate this, or get close to replicating it with a web application.

How often do you guys do something like this? Dig up an old project you've abandoned for one reason or another? I'm guessing this is a pretty regular occurrence for web developers.

On a side note, I fired up a new Rails application the other day and it's funny how BULKY Rails seems after a solid 3 or 4 months using Sinatra.

Sunday, January 22, 2012

CODETOBER, other code-related things I've been up to

As you may (or may not!) be aware, I've been doing some consulting work with the Expected Behavior guys the last couple of months, mostly working on SEO for DocRaptor, but also doing some other marketing work.

This applies to coding because they want a way to more accurately track where their users are coming from, so this week I'm going to look into coding something that will pull various bits of information into a more readable format. Sound cool, right?

I've also got an interview at iGoDigital on Tuesday, for a junior developer position. I interviewed there back in September, but it wasn't a good fit at the time. Now? Maybe a better fit! It's kind of funny. When I first got into Ruby, I wanted to make more money and programming seemed like a good way to do that. Now I'm less concerned about making more money, and I largely want to become a better programmer. Working full-time would definitely help me improve my skills, especially in a team environment. So I'm pretty excited about this opportunity.

I'm still gathering ideas for CODETOBER, since I really need to a) code more and b) blog about coding more. So far my list is pretty sparse, and I'm still open to suggestions if you've got them. What kind of things should I be looking into? What would be worthwhile, or valuable, or fun, or frustrating, or otherwise teach me a life lesson? I'd like to see more developers doing crazy things in February.

Now I think I'll sit down and work on a stupid project. I'm kind of losing interest in Dungeon Crawler (SURPRISE!)

Tuesday, January 3, 2012

Learning How to Abstract Code

In my last post, I was talking about how to deal with coder's block. I've been working on my current project, Dungeon Crawler, for about a month and I'd really hit a wall.

The problem was due to a couple of things. First, I'd gotten a lot of really good advice that I didn't quite understand, and I felt bad that I wasn't getting it, so I was reluctant to ask for more advice. Second, I'd already spent so much time without making any progress that I was getting sick of the project.

But I think I've gotten through my lack of motivation and I've made some progress with this project, but the code is an explicit, redundant mess. So the question at this point becomes is it better for me to make some progress coding in a way that I know is bad, or to not make progress at all?

Obviously it's better to make progress (and I did learn a bit about YAML tonight, so it's not entirely a wash) but it's about time I got better at writing code. I've noticed a problem with the way I write code: I'm far too heavy handed and I repeat myself too much. I need to get better at abstracting my code, so that's my current goal.

Maybe this is easier said than done, but at least I'm losing track of time while coding again, right?

Friday, December 30, 2011

How do you deal with coder's block?

I've kind of fallen into a trap with my Ruby work. I've been working on Dungeon Crawler for so long that I'm getting sick of it. I've had help from several friendly Rubyists (@jqr, @mileszs, @netshade, I am looking at you here) and I simply can't figure out how to make a proper redirect based on a form input.

This is extra irritating because I'm pretty sure I DO get how routing with Sinatra works, but starting a user out on one page with an input form, then redirecting that user to another page based on his input, seems to be escaping me.

I've gotten this to work in a limited capacity, when all of the logic is thrown into the

get '/input' do

method, but using a case/when statement here always uses the same logic. For example, dais_room will be north of torch_room, but vine_room will be north of dais_room, and I was always being redirected to dais_room with input "go north."

I also had a problem of simply being redirected to a white page with black text pulling the description of the room. I believe this was the method @netshade showed me for automatically creating a room without explicitly coding it, but for some reason it was not loading a view file.

Here's a full gist of what I've got, if anyone wants to give me some srs help:

Dungeon Crawler full gist

What do you guys do when you get so frustrated with a project? Do you power through, work on something else, or just take a break? I feel like since the holidays began, I've found a ton of great excuses not to code. It's Christmas Eve! It's Christmas! I just had LASIK surgery done!

But I'm sick of making excuses and I want to get back into working on a project without feeling like a gigantic dummy or just tearing my hair out because I can't figure it out. That makes sense, right?

It's not all bad news, though. @netshade and @annamul gave me The Pragmatic Programmer, a philosophical/theoretical book about coding. I really like the PragProg guys, and this book has been a lot of fun to read so far.

I think I need some way of setting goals for myself each week with coding. As in, "This week get better with using Git for source control," or "This week, get more comfortable with Javascript." Any recommendations for simple goal setting applications, or methods you've used? I use Tadalist for simple day-to-day chores and things, but that's not quite what I want. Maybe Evernote would work? I still haven't checked into that.

Either way, thanks for all your help, everyone! And Happy New Year!

Wednesday, December 21, 2011

Working with the Method method in Ruby

So with the help of my friend Z (also known as Chris to some, mostly just his wife) I've made some progress on Dungeon Crawler. But not much.

Namely, he showed me how to abstract my routing, so rather than having

get "/torch_room" do
  @torch_room = torch_room
  erb :torch_room
end


I have a method that automatically builds a route based on methods that already exist for rooms. Pretty awesome! I think learning to be less specific and abstracting my code is one of the most difficult things I'm learning. One of the guiding tenets of Ruby is DRY (Don't Repeat Yourself) and I really just need to be aware when I'm writing the same basic code more than once that it can probably be abstracted.

Ok, but here's my problem. I still can't figure out a way to collect input from a form, pass that input into an instance variable so that I can check it from other rooms and perform redirects based on the input itself. Does that make sense? I am absolutely trying my hardest to be clear about what I'm trying to do. Z also clued me in on a Method method but I can't figure that out, either.

Here's a gist with what I've done so far, but (FAIR WARNING) it's straight up busted:

Busted Gist

That said, I've noticed a funny thing about this problem. Bear in mind I've been wrestling with this guy off and on since my last post. (I DID do a couple of fun tutorials in between wrestling matches, mostly to keep myself limbered up) I didn't get frustrated in the usual "FUCK IT I GIVE UP" kind of way, but more in a "huh that didn't work. Ok let's try another thing. Hmm nope, that didn't work either," kind of way.

I did try some CRAZY other things, based on what my friend Miles told me about last time I posted about this problem (said crazy things mostly involved working with hashes, trying to convert hashes to strings, etc. Does that work? PROBABLY, I DON'T KNOW!) with minimal success.

I think this is how Daniel-san felt when he realized the entire time he thought he was washing Mr. Miyagi's car, he was actually learning karate.

Tuesday, December 13, 2011

Trouble with Ruby form methods

I'm still working with my Dungeon Crawler Sinatra app. Believe it or not, I have a problem. I'm trying to get a simple form method working to allow a user to move from one room to another by typing in the direction he wants to move and then hitting 'Submit'. So good so far, right?

Here's a link to a gist of the code I've got so far:

Working with form methods

The second file I posted in the gist is code that works, but I'm looking for a cleaner way of manipulating the information collected from the form method. Does that make sense? This is probably easy enough to do, and @jqr gave me some help with it last week, but I can't figure out how to make these form methods behave.

On a side note, do you have a problem with getting distracted with new ideas for projects when you're in the middle of a project? This seems to happen to me all the time, and I've been handling it by saving as much as I can think of in a Google Doc. I wonder how other programmers handle this? Do you just write things down in a notebook? I've been thinking about creating a template to use for these project ideas, just to keep my thoughts a bit more organized. If any of you have a template like this, or suggestions on what would be key features, I'd love to hear them.

I actually think a simple drawing application that allows me to add notes and save to the cloud would be ideal, but I haven't heard of anything like this.

Wednesday, December 7, 2011

More work on Dungeon Crawler

So my current project is coming along pretty well. I had an "AHA!" moment the other day (partly thanks to @jqr's hint about how to interpret gets.chomp) when I realized I need to use a form to collect that data. Once I've actually GOT some input from a user, it's easy enough to manipulate that information and make things happen.

I've drawn out the map of the entire dungeon (to help with actually laying it out when coding) and I've written methods and routes for all the rooms. Currently I'm loading a separate view for each room, since I eventually plan to have hand-drawn images representing the rooms themselves (which get updated when things happen, such as chests are opened, items discovered or moved, etc) so I thought this was the best way to handle it.

I've thought of ways to do the entire dungeon with a single view file and simply loading different information when the player makes certain choices, but for now I'm leaving that for a refactoring. Strangely enough, I think the hardest part of doing it this way would be figuring out a method for changing the image that represents the room, not the actual routing or the get method that would change the room. Strange!

I'm also not worrying about the individual features of rooms just yet, such as locked doors, traps, monsters and so on. My immediate goal is to be able to move throughout the entire dungeon, making sure all the routing works correctly and that you can't move into a room you shouldn't be able to.

Sinatra has proved a lot of fun to work with, in addition to being incredibly simple. It's kind of fun to have to do my own routing, too.

Also, I think it's important to name a project, so I'm calling this one Dungeon Crawler. (This was always the name of this project, even when it just lived in a Terminal window, but I'm not sure if I've mentioned that here or not)

Finally, I learned a great trick. I'd originally named my .rb file "dungeon_crawler.rb" and it quickly became tedious to type "ruby dungeon_crawler.rb" in the Terminal every time I make a change and have to reboot Sinatra, so I renamed it to "dc.rb". Much less tedious! My guess is that coders learn tons of tricks like this over the years.

Sunday, December 4, 2011

Making a web game with Ruby

Tonight I sat down to work through a bit more of Learn Ruby the Hard way (seriously, I'm on lesson 47 out of 52, I really should just finish it) but it didn't take long for me to get antsy to work on an actual program. Here's my current idea:

Building on AAN and Skyrim Stories, I want to take the dungeon crawler I made back in the summer, add some "awesome" hand-drawn graphics, and make it playable online. So far I'm picturing this as a Sinatra app, since it's pretty small and I won't need a database, and I can use Yaml for room descriptions. I've thought about ways to display different graphics for rooms when certain events happen, and I need to figure out how to take input from a user when an application is running on the web.

How do you collect information from a user, manipulate it, and trigger other functions based on the input when an application is running on the web? I'm unclear as to what the web equivalent of input = gets.chomp() is.

This project is largely just an excuse to take code I've already written (for the most part, it'll have to be refactored a bit for the web) and get more comfortable with getting a Ruby application to run on the internet. On top of that, I'm big into video games myself, and I'd love to have a hand in making games. Ruby probably isn't the best choice for making a game, but whatever!

Monday, November 28, 2011

Random Video Game Name Generator with Ruby

I've been working with a LOT of Javascript lately. And when I say "working with," what I mean is "finding scripts that will do what I want them to do and modifying as necessary." Wait, isn't this supposed to be a Ruby on Rails blog? What happened!?

I got back to work on my random video game name generator tonight. I basically wanted to style it a bit and find a way so that it would generate a new phrase whenever the page is reloaded and then provide a link to reload the page. Pretty easy to do with a Javascript code, but I'm not a huge fan of reloading the entire thing just to reload this bit of text. Probably a better way to handle this, right? Maybe an Ajax call? What do you guys suggest? This works but I don't like the look of it, I guess.

Anyway, here's a link to the app on Heroku:

Random Video Game Name Generator

I wanted to accomplish a few things with this project. First off, build a random name generator with Ruby, and then figure out how you run that code on the web. This was largely a matter of learning Sinatra, and when I say "learning," I mean reading a tutorial and talking to @jqr about it for a few minutes. Sinatra is like SO easy.

I've got plans for how I could expand it (don't I always? Other coders have this problem too, right?) such as allowing users to save names they especially like, then enter a short description of what the game would be like. Viewers could also look at games that had been saved, perhaps vote on them, look at most popular games, etc, etc.

I think it's getting easier for me to think about WHAT applications COULD do, now that I know a bit more about HOW they're built. That makes sense, right?

Wednesday, November 9, 2011

Finished random name generator in Ruby

I've finished up a working version of my random name generator. Here's a gist of the code:

Random Name Generator

I'm calling it aan (short for adjective, adjective, noun) because the original was just three phrases slapped together. Now I've added functionality that will generate a prefix or a suffix (seemingly) at random. I might spend a bit more time working with this. It's been a fun little project and I'd like to make a Rails project for it so I can put it up on Heroku and show it to non-coders.

Some other things I may look into:

A way to output the full name on a single line. I tried print instead of puts, but it simply outputs the pieces of the array, not the entire string built from the various arrays.

A way to capitalize every word except for words like "of", "the" and so on.

Using this with other data. What about a Full House episode plot generator? What if instead of specifically saying "Uncle Jesse takes Stephanie to the movies, which makes DJ incredibly jealous" I had "DAD takes DAUGHTER1 to the EVENT, which makes DAUGHTER2 incredibly jealous" and I passed in variables, to further randomize output? Maybe this will be my next project. It kind of combines stuff I was doing with the MadLib generator and this random name generator.

One of the things I like most about Ruby is how much you can do with it once you have an idea of what you're doing. I've definitely got a better idea of how reading files and using data found in those files works now. It's also pretty awesome to sit down for a couple of hours and bang out a working program.

I've also found that since I've become less focused on making a career change and more interested in learning how Ruby works, I'm having a lot more fun coding. That's a plus, right?

Monday, November 7, 2011

Random Name Generator with Ruby

I like making stupid things with Ruby. Last week I was working on a MadLibs generator, not because I have an uncontrollable urge to make MadLibs, but because it was a project I could understand and I wanted to build.

My friend Eli showed me how to refactor the code so it was less specific and therefore much more versatile. Whereas the code I wrote was very specific to one MadLib, the one Eli helped me write is far more general, and can make MadLibs out of any text file that's been prepared (substituting all instances of a noun with NOUN, or NOUN1, NOUN2, etc, for repeating nouns)

It's obvious to me how valuable separating logic and data is, but it's going to take some work for me to really wrap my head around this. I've been coding with my logic and data entwined in a big hot nasty mess for a while.

Here's a gist of the finalized, objectified MadLibs generator:

MadLibs Generator

So my next goal is to take what I learned with refactoring the MadLibs generator and make another stupid project. I ran across this site a few nights ago:

Video Game Name Generator

So I've decided to build one using Ruby. I'm calling it aan so far (adjective, adjective, noun) and I've got a version working that will generate random combinations from pre-defined arrays, but I'm working on expanding it so it will read text files and generate lists from those files.

Once I get THAT up and running, I want to work on making it a bit more complex. Adding support for generating names that may or may not include a prefix or a suffix in addition to the standard adjective-adjective-noun, for example.

I think I'm having a lot more fun with coding when I'm working on stupid things like this than when I was working on larger-scale projects (long tutorials, Manticore, Chorenivore) but it's hard for me to objectively say which is more valuable.

Sunday, October 30, 2011

Refactoring Ruby Code

Since I've been working on this MadLibs generator, I've been through a couple of refactorings. Friday night, I got the code hammered out but I ended up with this:

MadLib Generator, first version

It works, sure, but it's ugly. A ton of gets.chomp()'s, and there's obviously a better way to do it. Still, my plan was to hack it out as best I knew how, identify problems with it, and then rework the code.

So here's my second attempt:

MadLib generator, first refactoring

Not bad! I've gotten rid of all the gets.chomp() commands in favor of loops that will collect the correct number of nouns, verbs, adjectives and so forth. I also got rid of the prompt method - it's a hold over from the dungeon games I've been working on and I felt it was unnecessary. I was pretty proud of this, but my friend Eli thought it could be refined further, suggesting I try to Objectify the code. I'm a bit puzzled by this. What does this mean?

At any rate, I took another look and here's what I've got now:

MadLib generator, second refactoring

In this iteration, I cleaned up what's being collected a bit, and took out the definitions for popping words out of the arrays. I realized I could just call the .pop method directly by defining the array as an instance variable. This way, I was able to shorten the code by several lines by adding a character to each variable. Pretty good trade off, if you ask me!

I also redefined each array after calling a .reverse method on it. Since I'm using .pop to pull words out of the array to place in the Mad Lib, this will keep the words in the same order the user entered them.

Things are going pretty well. I feel proud that I'm anticipating problems and finding solutions for them now. Also, I should've been using Gists for a long time now.

Friday, October 28, 2011

Require - No Such File to Load Ruby

The exercise I'm working through in Learn Ruby the Hard Way has me spending a week creating my own game. I've been building various text-based adventure games, but was stuck on what to do next. This morning on the way to work I got the idea of building a MadLib generator.

The way I picture it working is like this: the generator will ask the user to select a Mad Lib from a list, then ask for the requisite input (nouns, adjectives, verbs) depending on the Mad Lib selected and finally spit out the finished product. Simple, right?

So my thinking is this project would be split into two parts: the main program that asks for which Mad Lib the user wants to do, and the Mad Lib that is loaded upon selection. To get this up and running, I decided just to make one Mad Lib work at first, then add support for multiple Mad Libs and the ability to choose between them.

This is just a simple matter of requiring the Mad Lib file from the Main file, but I ran into a small problem.

Using the require 'mermaid' command threw this error:

<internal:lib/rubygems/custom_require&rt;:29:in `require': no such file to load -- mermaid (LoadError)

I wasn't sure why this wasn't working, since I've used require to load separate .rb files before. After a bit of digging around, all I had to to do fix this problem is change require 'mermaid' to require_relative 'mermaid'. This makes sense - both files are in the same directory, so this command is simply saying to require this file located in the same directory as the main file.

On a side note, I'm glad to have fixed the problem, but I'm getting to the point that I think it's better to understand WHY things don't work, rather than finding the solution and moving on. Can anyone tell me why 'require' wasn't working, but 'require_relative' does? Is it an older style of Ruby code that's outdated? Do I need to change some configurations? Is require_relative a workaround? Where does require look for files, if not in the same directory the file that's making that call is located?

Anyway, it felt good to make some progress on this tonight. It's pretty awesome that I can come up with an idea on the way to work, come home and put it together in an hour and a half or so. I think this will be a fun little project. I plan to work on it more this weekend, expanding it, polishing it up and so on. Here's a link to the gist I made of it:

MadLib Generator

Wednesday, October 26, 2011

Initializing Classes in Ruby

I definitely tend to jump around a bit when it comes to learning to code. I was working on Manticore quite a bit, then jumped into Learn Ruby the Hard Way, and now I've hit a bit of a snag so I checked out Code School and the introductory Ruby lesson. (This lesson is based on Why's old lesson, by the way, and is awesome so far) I'm a big fan of Code School so far, because hands-on, practical tutorials have always been one of the best ways for me to learn.

Much like Learn Ruby the Hard Way, it's a lot of review, but I've been interested in seeing what Code School has to offer for a while. Not to mention, switching gears slightly seemed like a better use of my time than sitting around frustrated because I wasn't understanding defining Classes and initializing them properly. I also think the more time I can spend having fun with Ruby, the better. I end up coding longer and enjoying it more, which leads to me learning more and it all kind of snowballs from there until I can build a sort of half-ass snowman with string literals for arms and instance variables for eyes.

Still, Ruby isn't all string methods and arrays, so I'll get back to my problem with Learn Ruby the Hard Way pretty soon. Probably tomorrow!

Here's the basic problem: I have one Class, Game, and the extra credit for this particular exercise is to break the Game into two Classes: Engine and Map.

Here's a link to a gist of what I've got:

Gothons Attack!!

What I'm assuming I need to do is break the rooms a player goes through (methods such as :central_corridor, :bridge_access, etc) into the Map method, and put the code that drives the game into the Engine method. So now I need to learn what initializing a class does, how to do it, how to call a method in one class from another class, and how to make two classes work in concert. For example, Engine will be starting the game (I assume) and moving the player through the rooms that are defined in Map (I also assume) Any input on this problem is, as always, HIGHLY appreciated!

I used to think of learning Ruby as unearthing this huge artifact, but now I think of it as being inside of a mostly darkened room, where I'm stumbling around and looking for switches. Once in a while, I flip a switch and it might illuminate a far off corner, or a whole corridor, or just a tiny little piece of the room. Does that make sense? Or in other words, learning how to do new things is really frustrating right up until it's not, and then it's awesome.

Sunday, October 23, 2011

Here documents in Ruby

I'm still working through Learn Ruby the Hard Way, and the last few exercises have been about building simple text based dungeons. You may recall I spent about a week working on one of my own. This latest exercise introduced me to here documents.

A here document is an easy way to display a long, multiline string. This would have been PERFECT for use in my dungeon adventure. Here's how it works.

This is the original description from the first room in the dungeon game I built:

  puts "This room is dimly lit by two sputtering torches."
  puts "There are three doors leading out of here."
  puts "What do you do?"

You may notice a few "puts" methods. It's not terrible in this case, since I'm putting several small statements, but it's tedious to type and unnecessary to use so many methods when you could do it with one here document. So forget what I said. There's a better, simpler way to do it, so it IS terrible!

So this example can be re-written like this:

  puts <<−TORCH_DESCRIPTION
  This room is dimly lit by two sputtering torches.
  There are three doors leading out of here.
  What do you do?
  TORCH_DESCRIPTION

You begin the here document with <<−TORCH_DESCRIPTION and end it with TORCH_DESCRIPTION. Ruby interprets everything in between as one string. Cleaner, right? Easier to read? Who wouldn't love it!

On a side note, you CAN write this as <<TORCH_DESCRIPTION instead, but by adding the minus sign, you can indent the code as usual. Without the minus sign, the terminator can't be indented, or else Ruby will start complaining about "can't find string TORCH_DESCRIPTION anywhere before EOF".

So I recommend using the minus sign. One more character makes your code a lot easier to read. I also ran into another little problem. Since a here document is a string literal, any variables won't be interpreted correctly. This is where interpolation comes into play. Here's an example from the current exercise I'm working through.

guess = gets.chomp()

if guess != good_pod
  puts "You jump into pod %s and hit the eject button." % guess
  puts "The pod escapes out into the void of space, then"
  puts "implodes as the hull ruptures, crushing your body"
  puts "into jam jelly."
return :death

This bit of code describes an escape pod room, where the user has to pick an escape pod to use. So we set the user's choice as "guess" and then call it in the method below. This is what happens when a user chooses poorly. However, if I were to rewrite the code using a here document, this is what I'd have:

  puts <<-BAD_POD
  "You jump into escape pod %s  and hit the eject button. %guess
  The pod escapes out into the void of space, then
  implodes as the hull ruptures, crushing your body
  into a jelly."
  BAD_POD
return :death

Now the %s and %guess won't be interpreted as variables, since they're inside of a string literal. Luckily, there's an easy solution: interpolation. Just swap out the %s for this little guy:

#{guess}

Ruby will look at this, understand that means you want to use a variable inside of a string literal, and then pull the information it collected when it asked the user which pod he wanted to jump into.

I'm hoping this post will be helpful for others who are grappling with here documents. It took me a bit of digging to figure out how to get the code to index properly (since it looked awful in Textmate, and my solution was to put the string in quotes, which was unnecessary) and I needed to figure out how to call a variable from inside the here document.

Sunday, October 16, 2011

Finished text-based adventure in Ruby

I'm now more or less done with the text dungeon I was building last week. I finished it up last night and fixed some bugs, refactored a bit and made the game more playable today. I also ran the code with -w, which shows a list of warnings. I'm not entirely clear how warnings differ from errors (other than errors stop the code, whereas warnings allow it to continue) but running the code this way allowed me to clean up bad indentation (plenty of it) as well as cleaning up a few other things. I also found out you can indent or unindent (is this a word?) a block of text in TextMate using keyboard shortcuts. Of course, I only found this out after getting frustrated at how long it took to manually indent or unindent a block of code. What's the lesson here? Sometimes it's not about learning new tools, but learning to be more efficient with the tools you already know. 

I've learned a lot with this little project: defining instance variables such as @brass_key, using instance variables to do things within other methods, such as opening doors, creating an inventory for the player that adds or subtracts items as they're found or used, logic to change events if certain instance variables were true and so on and so forth.


Tomorrow I plan to get back to work on Learn Ruby the Hard Way, but this week has definitely been well spent. I may revisit this project in the future and rewrite it to use case / while instead of if / elsif, but I'm ready to work on something new. I spend a lot less time flailing around and feeling stupid now and a lot more time coding or looking for ways to do what I want to do. 


My vocabulary is getting better, too, so it's easier to find information now. And all of this work makes me think about Manticore (don't worry, baby, I haven't forgotten about you!) and how much easier it'll be to redo now. The code I had before I sat down with Eli a few weeks ago took me a couple of months to write, and I'm pretty confident I can get the same functionality with less code in about a week now. But first I need to finish up Learn Ruby the Hard Way. 


And I've been thinking about using what I've learned to write tutorials. I'm sure other new Rubyists will be confused about local and instance variables, or how to write and call methods, and I'd like to try and write something up that will explain these basic ideas in the context of a text-based dungeon crawler. I haven't thought too much about it yet, but it's something I'd like to do in the future.


Here's a link to a gist of the game:

Dungeon of Unfathomable Horror

Tuesday, October 11, 2011

Calling a method in another method in Ruby

I've hit another turning point in my work with Ruby. I've slowly been getting more and more excited about coding, but this week marks the point that sitting down to code seems like something that's fun to do and not just something I kind of enjoy doing that I'm working on because I'm interested in a career change.

I had a really good day with the project I'm currently working on as part of Learn Ruby the Hard Way: a text-based adventure. It's a pretty simple concept, but so far I've got a working four room dungeon. And it's a game! Sure, it's a basic, text based game, not even as complicated as Zork, but it works! Do you know how awesome it feels to build something that works? REALLY AWESOME.

Today at work I was thinking of ways to expand it. How about adding a "help" command to give players some commands that will allow them to manipulate objects in the dungeon? How about a "look" command to remind players which room they're in and to point out important features of that room? How about a "quit" command to let players quit the game?

Done, done and done. Pretty easy: these were all just matters of defining methods and then calling them within the methods I've defined for the various rooms. For example, here's the "help" method I made:

def help()
  puts "Here's a list of handy commands to help you in your quest:"
  puts "Open: open doors, chests, your heart, etc."
  puts "Look: get a description of the room you're in."
  puts "Take: take an item and add it to your inventory."
  puts "Inventory: see what items you're carrying."
  puts "Quit: quit the game, as a coward would."
end

And then I wire it up in each of my room methods, so in the torch_room method, I use this code to allow a player to call up the Help menu:

if next_move == "help"
  prompt; next_move = gets.chomp
end

As I may have mentioned before, I don't have much coding experience with other languages, so I don't know how easy it is to add functionality, but it's really easy with Ruby, and that's part of what I love about it. I'm having a ton of fun with this little project, and while I did a similar project when I was working through Beginning Ruby, those were different times. It was a matter of simply copying code at that point and not understanding what I could do with Ruby and how to make it do what I want it to.

I'm not saying I've mastered Ruby (not by a long shot!) but I'm definitely getting better and it's getting more fun the more I learn. My goal is to keep working on this dungeon for a few more days, expanding the number of rooms, adding monsters and traps, coming up with an inventory system and so on before I move forward with Learn Ruby the Hard Way.

Sunday, October 2, 2011

Using Ruby to Solve Problems

This past week I've been working through Learn Ruby the Hard Way. It's really a great resource (as I've mentioned a few times already) and I'm picking up lots of good habits. Here's a little example:

I work full-time doing SEO for an e-commerce site, and a while back we ran into a problem on our site with duplicate content. We needed a simple tool for entering two blocks of text and calculating how similar they were as a raw percentage. We eventually found some tools, but they weren't quite what we needed and weren't that great.

So I got the idea of building something using Ruby to do just this and spoke to my friend Eli about it. I still haven't actually BUILT this little program (and I'm sure it WOULD be little, at least at first) and part of the reason was that I didn't have a great idea of HOW to build it. I assumed I might have one model, say Text, with two textarea fields that could be compared, then spit out a percentage for similarity.

Obviously, I'd be using Ruby to make this calculation and that would be a matter of defining a word, counting instances of words, and then making a comparison between both blocks of text.

I've been doing a lot of work using Ruby to open and edit files, so it's obvious I could do similar operations to open and compare files, then generate a report based on that comparison. Not an elegant solution, since users would want to paste text into fields and compare them, not upload files to compare. But I'm sure it's doable. So that might be my next project.

I kind of tend to bounce around between projects, but I'm learning the entire time, so I don't feel bad about it. That's what these projects are for, right?

I also tend to think of an idea, and immediately think of ways to expand it even before I have the original idea working. For example, I'm already thinking of how this project could be expanded to do other things with text, such as identifying words that are used too frequently, identifying passive voice, identifying and suggesting replacements for adverbs and so on. In this case, I think it's because the original problem seemed to be "How can we identify content that's too similar in terms of SEO?" but I've begun thinking of it as "How can we write better content for the web?"

From my limited experience and understanding of web development, programming and computer science in general, it seems to be a matter of identifying a problem and then finding a solution. Am I far off the mark here?

Tuesday, September 27, 2011

Learn Ruby the Hard way

So I was all amped up and ready to get back to work refactoring Manticore tonight, but I ran across this site last night:

Learning Ruby the Hard Way

I've been meaning to beef up my Ruby skills, and although this site is largely review for me, I think it's GOOD review. I'm definitely getting in the habit of commenting on my code, which is something I've been meaning to do for a while now. I'm already through the first four exercises, so I don't anticipate this taking very long to get through.

When I first started learning with Beginning Ruby, I read through a bunch of Ruby code, but it wasn't very practical, since I had yet to get my filthy mitts on Rails. And now I've been hitting Rails pretty hard for a few months, and while I've used Ruby here and there, I've been feeling like I needed to get better acquainted with it. So here we are!

This is a good resource, and I wish I'd found it (or it had been available) when I got started. It's well written, engaging and doesn't hold your hand too much. The author assumes you can do some basic things, such as researching terms you aren't aware of and figuring out why an error happens when it does.