Ruby & Ruby on Rails Methods for Discovery Part 1
When I program I see it as both an art and a challenge. The art is in the how. The challenges I see as detective work. The answer is unknown as of yet, and it’s your job to sleuth it out. A detective hunts down the clues until an answer is found. Yes, that is programming.
To increase your abilities in programming exponentially you need to improve your toolset. And if you’re curious as to what I mean by toolset I am referring to the methods for solving problems which you store in your mind.
This post isn’t about reading a book, taking a class, or doing some online puzzles. This is about methodology. This is about worldview. This is about perspective.
If you’re new to programming this may be insightful. If you don’t grasp some of what’s being said that’s okay. All the more reason to continue. Any detective loves a good challenge.
Well I want to get right into details so lets get on to it shall we? First thing’s first. When learning Ruby it’s best to experiment in your irb terminal. You pick an area you’re not familiar with and you let the language build the context for you. Then your perspective will build. For example: there is a little used method in ruby called tap. If you’ve never used it before then the name is meaningless, it has no context for you and perception is vague at best. Normally you will discover it by either seeing it written in code, or being told about it. It’s not a method that comes out and introduces itself to you. So let’s say I give you a hint. I’ll be the one telling you about it. “tap lets you modify the Object you apply it to.”
Now I wasn’t very helpful in spelling out everything. I only fed you enough to get the gears in your mind working on it. Now you have “some” context and a little perspective. Your mind will start leading you on to many questions on what, how, and where. This is good. Curiosity may have killed the cat, but it pays the programmer dividends. Lets start thinking out loud.
So tap lets you modify an Object… how might I go about doing that? Since I didn’t give you the how, you can see since I said “the Object you apply it to” that you can do it on an Object. Well 1 is an Object, so lets type 1.tap and see what happens. It outputs: “LocalJumpError: no block given“. Congratulations! You’ve found a piece of the mystery by simple experimentation. We now know that tap takes a block!
What’s important here is the method of discovery. You will find more and more diverse ways to discover many mysteries and then things become clearer and exciting.
Let’s step it up a bit. Now if you’re experienced with using blocks you know how they work. If not then it’s best to both read about them and experiment. With knowing how blocks basically work we can determine a “most likely” scenario. We know tap takes a block and modifies the Object it’s called on. So to handle modification within a block from the Object outside a block we know we need to “hand it inside” the block through a variable. That, for those who know, is done within the pipes || with a variable name |variable_name_of_greatness|. Also this needs to be inside the block as such {|variable_name_of_greatness|}. If you experiment with other blocks you will find they don’t work in the same manner. For example this {|x|} in no way works like this begin |x| end. This is just some basics though.
So back to it. We’re handing the Object in to tap through a variable. Lets try 1.tap {|myvar| puts myvar } and it prints out 1. Continuing to experiment we try 1.tap { puts self } and get main as the output. Here we can see that even though tap is made to modify the Object, we aren’t inside the scope of the Object while in the block. Now let’s use tap as it was intended… to make changes. What happens when we do “a”.tap {|var| var.upcase } ? … it returns “a”. Wait a minute… that’s not what was expected right? What about “a”.tap {|var| var.capitalize } ? … it returns “a”. So what are we missing here? Then your minds gears kick in and you think… maybe I need to return the result? So you try: “a”.tap {|var| return var.upcase } and you get “LocalJumpError: unexpected return“. This didn’t give you an answer, but it did show you one wrong way of doing things… it’s a clue.
If you’re getting impatient then you aren’t honing your curiosity. Programming involves a lot of sleuthing. It isn’t always a quick process. Yes you could have looked it up already. But part of the fun is the discovery and the challenge. Remember I’m suggesting your toolset is your mind, not the websites you reference. You want to always improve upon your mind to maximize your effectiveness and efficiency.
Now I’ll got ahead and give you some more insight on tap. We can make “a”.tap {|var| var.upcase } pass by calling replace on it. This is specific to the String Object only though. So “a”.tap {|var| var.replace var.upcase } return “A”. But if you try 1.tap { |var| var = var + 2 } you end up getting 1 as the response which didn’t work out. That’s because in general tap isn’t modifying the outside Object directly, it is technically tapping into the Object. If you think of it as an Object that has internal values that you want to do something with; then tap is a great choice. Here’s one great use case. Let’s say you want to scrape a website for information but the the site redirects. Well normal page scraping won’t follow the redirect. But with Mechanize you can tap into it and set a flag of following refresh to true Mechanize.new.tap{|i| i.follow_meta_refresh = true }.get(“http://www.example.com”). Here we modified a value inside the instance of the Object Mechanize. This also shows a reason why I like tap. It’s because you can use it inline, it returns self, and you can continue chaining additional methods on the same line.
There are so many things I could share with you young padowan. I’ve shared with you the mindset. Now I’ll share a few great tools to utilize and experiment with. To explore your environment you can use the methods: methods, method, local_variables, instance_variables, and constants. If you’re using a more recent irb version then when you start typing a method you can press the tab key twice to list possible methods. You can try the gem pry which is designed to allow you to explore your code just like you would your operating system. I will endeavour to go over these methods, and techniques for them, in future writings.
As always when experimenting it’s okay to read the documentation for the language. Just make sure your mind is curious as you read the docs for “what if” and that you experiment with that curiosity to maximize your software detective sleuthing. You are a Private Investigator in Software Development: PISD 😉
Here are some excellent language reference sites you should keep handy: https://rubydocs.org/, http://ruby-doc.org/, http://apidock.com/, and my personal favorite https://www.omniref.com/.
Lastly I want to say that in general StackOverFlow.com is a good place for finding answers… but it’s becoming a poor place to ask them. If you do choose to use it please read the policy for asking questions. They ask that you put in best efforts in finding your own answer before you ask. Don’t ask a question that has already been asked. Be clear with what you’re asking as people often misunderstand. And if you’re going to ask questions, then please make it a practice to answer questions. The reason I say it’s becoming a poor place to ask questions is because everyone gets referred to that site to ask questions… this has lead to an overwhelming flow of questions being asked (many who obviously didn’t read the policy), and the people who have been answering aren’t able to get to all of the questions. So please consider StackOverFlow as a website to “contribute” help to. Be positive, always upvote both useful questions and useful answers. The site could use a little more sunshine, and you may be just what it needs. A long insightful answer is always better to give. So use your sleuthing skills, experiment, and give a great answer. I love StackOverFlow. I think everyone should use it. But be good to the developer community and don’t abuse it.
Please comment, share, subscribe to my RSS Feed,and follow me on twitter @6ftdan!
God Bless! -Daniel P. Clark