More RubyMine Shortcuts for Faster Development

RubyMine isn’t vim but you can still use keyboard shortcuts to speed things up. Here are a few more of my favorite keyboard shortcuts.

  • Shift + Esc
    Hides the last active window.  This is especially helpful when you want to hide the testing window or the project window so that most of your screen is only code windows
  • Ctrl + Alt + M
    Extracts a method that contains the currently selected text.  Very helpful when breaking up large methods.
  • Shift + F6
    Rename the currently selected text.

 

Related Posts

A Few of My favorite RubyMine Shortcuts to Speed Up Development

Speeding up Ruby Development on Windows using RubyMine

Refactoring isn’t just for code

Earlier today, I came across this post where screenwriter John August ‘refactors’ Katy Perry’s recent single Roar . It is interesting to see how he goes through the process of coming up with better lyrics by trying several intermediate steps as well as trying to identify the true intention of the lyrics in the process.

Hopefully you can get something from the post that might allow you to look at your code from a slightly different angle in order to come up with something better in the end.

 

Using Ruby’s Scan Method to Transform Strings

In the last post, I came across the line below that worked fine but I wanted to make it more compact and introduce some reusability for the future.

The problem that needed to be solved was to take a three character string and convert it to a six character string by duplicating each of the characters while keeping the duplicated characters together.

For example, the string ‘fd3′ should become ‘ffdd33′.

After looking through the Ruby Docs for the String class, I came across the scan method that looked like it would help solve the problem.

The explanation of the scan method from the Ruby Docs:

scan(pattern) → array
scan(pattern) {|match, …| block } → str

Both forms iterate through str, matching the pattern (which may be a Regexp or a String). For each match, a result is generated and either added to the result array or passed to the block. If the pattern contains no groups, each individual result consists of the matched string, $&. If the pattern contains groups, each individual result is itself an array containing one entry per group.

To get to the end result, the following steps were used:

1.  Use a regex to match each individual character and return an array of the characters.

?> (‘f3d’).scan(/./)

=> [“f”, “3”, “d”]

2.  Because we want to keep the duplicated characters next to each other, the regex is changed to group each character by itself.

?> (‘f3d’).scan(/(.)/)
=> [[“f”], [“3″], [“d”]]

3.  Now that each character is grouped by itself, the regex can be used to duplicate each character.

?> (‘f3d’).scan(/((.))/)
=> [[“f”, “f”], [“3″, “3”], [“d”, “d”]]

4.  Flatten the array to remove the sub-arrays.

?> (‘f3d’).scan(/((.))/).flatten
=> [“f”, “f”, “3”, “3”, “d”, “d”]

5.  Join the elements to give us the result.

?> (‘f3d’).scan(/((.))/).flatten.join
=> “ff33dd”

The downside of this change is that the code might be considered less readable by some.  There is also a bit of premature optimization going on here but I think it’s not an unreasonable change because this code is more reusable if requirements change in the future.

In any case, I felt it was  a good way to demonstrate the power of the scan method and I think it works well for this application.

Refactoring Untested Case Statements in Ruby

I recently came across a small Sinatra app called PixelHoldr that generates placeholder images for your site based on the options you pass in through the url. This is a handy little addition to a web developers arsenal so I decided to take a look at the code.

There isn’t a lot of code necessary to run the app but there was a case statement that jumped out at me immediately. The Gist below shows the method that will be the example for this post.

I also gave it a quick check on Code Climate to see if the the score is improved once the method is refactored.

pixelholdr-get-hex-start

 

After poking around the PixelHoldr source, I found that there were no tests so that was first on the agenda. I also wanted to move the functionality into a class so that the functionality was encapsulated in an object with a name that represents its function.

I used TDD to drive the class creation but because there were no existing tests, I simply copied the get_hex method directly into the class and set up an initializer that will accept the color parameter.

At this point, I worked backwards to create tests that would validate the current functionality.  This would give us the tests needed to refactor the logic within the method. It was also during the test creation that I changed the get_hex method name to generate_color because that seemed to better convey the action being performed.

Now that the tests are in place, the method can be refactored without worrying that bugs are being introduced.  I’ll save the step by step at this point because the changes are easy to read.  The refactored class is shown in the gist below.

After pushing the class up to Github and running it through Code Climate, you can see that the end result gives a much better score.

after-pixelholder-get-hex-refactor

 

See the associated files for this refactor on Github:  PixelHoldrRefactor

A Few of My favorite RubyMine Shortcuts to Speed Up Development

As a developer on the Windows platform, it’s very difficult to stop reaching for the mouse but I’ve been trying to wean myself from the mouse as much as possible.  Here are a few of my favorite RubyMine shortcuts that have helped.

  • Ctrl + W
    Selects the nearest word.  Repeatedly pressing them will select increasingly larger blocks of words.
  • Ctrl + /
    Toggle commenting on the selected line or highlighted block.
  • Ctrl + Tab
    Navigates through the files that are open.
  • Shift + Delete
    Deletes the current row and places it in your Clipboard to paste later.
  • Ctrl + Alt + M
    Extracts the highlighted block of code into a new method.

Refactoring the CategoryList class in Discourse

The CategoryList class in Discourse provides a good opportunity to bring up an issue that you might come across often, which is that the method that needs refactoring is a private method.  In this case, the CategoryList#add_uncategorized method is private but is in need of refactoring to break apart the many different tasks the method is performing.

This could be an issue because the tests for the class only test the final outcome of the public method that calls the private methods.  This is exactly as it should be, but I often find that a method that does way more than it should does not have sufficient testing.  The fact that this method is private complicates things because you have to make certain choices on how to proceed.  Often, the easiest way to tell if the testing is suspect is to remove a block of code that looks like it should cause the method to alter its outcome and in return cause the tests to fail.  If you do this and the tests still pass then you want to check it out more thoroughly.

My preferred method of dealing with private methods, especially in less familiar code-bases, is to temporarily make the method public and write tests to examine the code better.  Once you have done this, you can move forward with your refactoring and have much more confidence that you aren’t altering the functionality in a way you didn’t intend.

For this example, I’m going to move forward with the assumption that the tests fully cover all intended functionality but I’m not going to push my changes up to Master because I do think more tests are needed. Adding those tests may be the subject of another post in the future.

As you can see, the starting point for the CategoryList class is pretty good.  The B grade for the class is only brought down because of one complex method which is what we will be working to make less complex.

category_list_starting_grade

 

The code of the method that we’ll be refactoring is below.

Our initial look at the method shows us several places that we could start with our refactoring.  I usually look for comments and if statements that allow us to begin splitting functionality into smaller methods.  This class has several calls to the Topic and Category classes that are also hints of where we can begin to refactor.

In this case, I chose to begin by moving the functionality that creates the various variables inside the method in order to simplify things a little before I continue.

The assignment to uncategorized_topics becomes:

The assignment to totals becomes:

The assignment to uncategorized is now:

Making these changes allows us to see the add_categorized method a little more clearly now.

Next, I create two new methods to encapsulate the functionality that inserts the category in the proper location and adding the uncategorized topics to @all_topics.

This leaves add_categorized with a lot less functionality directly inside the method.

Now that we have extracted the different types of functionality into their own method, we can turn our attention to refactoring each of the methods that were extracted.

The first thing that needs to be done is to move the calls to Topic into the Topic class itself.  This functionality is tied directly to Topic so that is the class that should handle this responsibility.  To do this, I created two new methods in Topic named totals and uncategorized_topics.

The get_uncategorized_topics and get_topic_totals methods can now be removed from the CategoryList class and those calls can be replaced with calls to the new methods in Topic.

The next step is address the creation of the new Category.  A better approach is to create a new class that is named appropriately and conveys the intent of what is being done.  This is accomplished by adding a new class named UncategorizedCategory that inherits from Category.

If you look at this class closely, you see that we simply pass the same object to the constructor of the class as we did when using the method.  The one difference is that we moved the call to Topic#totals to the initialization of the new class because it isn’t used anywhere else in CategoryList.

The last thing to address is the insert_uncategorized_category method.  I’m not a big fan of initializing a variable to nil if it can be avoided.  In this case, the more idiomatic catch/throw can be used to clean things up.

One last tweak we can make in the insert_uncategorized_category method is to remove the OR in the line shown below.

Since the OR is checking to see if our previous block returns nil, we should just move the value that we want to be returned instead of the nil.  The gist below shows this change.

At this point, the functionality has been separated out so that each method is responsible for a much smaller piece of the puzzle.  After merging the branch back into my local copy of master and updating the repo on CodeClimate, we can see that the grade has increased to an A.

category_list_ending_grade


One Final Note

If you were paying VERY close attention, you might have caught something that I haven’t touched on yet.  If you look at line 41 of the original gist you will see that this line just disappears. This appears to be a phantom line from previous functionality because it doesn’t really to anything as far as I can tell. If this is in your code, this is a tell-tale sign that you had better have comprehensive tests in order to have confidence in what you’re putting out there.

Speeding up Ruby Development on Windows using RubyMine

On many corners of the internet if you mention that you do Ruby on Rails development on Windows, you will immediately feel the earth shaking as the community starts laughing in unison and yelling at you to make the switch to a more Ruby-friendly platform.

I haven’t made the switch away from Windows, and yes, there are quite a few headaches to deal with but for the most part my productivity doesn’t suffer. One of the main reasons is that I’m using RubyMine.

I’ll make no secret of it, I have almost always* used an IDE because the majority of my programming was done on the Windows platform. When I moved to Ruby on Rails, a major project required that I didn’t lose too much time getting started so I chose RubyMine as my IDE so that my development environment wasn’t something that slowed me down.

Like a lot of developers, I too said ooh and aah when I watched Ben Orenstein’s presentation on vim but the learning curve wasn’t something I had time for. I chose RubyMine because of the ability to speed things up with keyboard shortcuts.  Here are a couple that I use regularly to get things done faster.

Fast File Navigation

Ctrl + Shift + N

Brings up a window that allows you to find files using fuzzy search.

ctrl-shift-n

 

Shift + Alt + N

Makes it easy to move between associated files.  For example, if you’re editing a model and you need to switch to the controller.  Use Shift+Alt+N to bring up a dialog box of all the associated files.

shift-alt-n

 

 

* back in the day I coded classic ASP sites in Notepad.  Pretty hardcore, I know.

** no, this post isn’t sponsored

Tell, Don’t Ask. Refactoring the SearchObserver class in Discourse

The latest class I came across in the Discourse code base provides a good opportunity to demonstrate the idea of “Tell, don’t ask”.  After seeing Sandi Metz’s talk at Ancient City Ruby, I’ve been very conscious of limiting any type checks or a lot of conditionals that collect a bunch of different logic in one method.

The starting point of the SearchObserver class in Discourse is a good example of code that does a lot of asking to determine what it is going to do.

The after_save method is full of type checks and if statements that direct the flow of logic.  My initial thought is that this class is taking on too much responsibility so I want to refactor the class to put the logic where it belongs and make the code more “confident”.

In order to get to the final result, I’m going to start outside of after_save method.  After examining the SearchObserver class, I found that the HtmlScrubber class is only used by the Post model.  With that being the case, it makes more sense for this class to reside within Post since that’s the only place it is used in the entire app.  If we needed this functionality elsewhere in the future we could put it into its own file but I don’t want to prematurely optimize anything at this point.

After copying the entire HtmlScrubber class into Post, I create a method named scrubbed_html and then make the changes inside the SearchObserver#after_save method to handle our changes.

After these changes, it makes it a little easier to see that each if statement eventually ends up passing the same three variables to the update_index method.  Because these three variables are passed together, it makes sense to create a separate value object that encapsulates this information. I’m going to start by encapsulating the id and search_data variables first because there is quite a bit of logic that surrounds which class type we’re sending to the update_index method.

After moving the creation of the search_data variable into the proper location in the after_save method, I can now create an object to pass the id and search_data variables, the SearchObserver class now looks like the gist below.

Now that two of the three parameters are being encapsulated, we can turn our attention to the third parameter.  This parameter is just a lowercased version of the class name which means we can pass the object itself into our value object to create this value. It will also give us access to the object’s id value that we were passing in by itself previously.

SearchObserver after the changes…

Now that all three of the individual update methods are identical, they can be removed and the value object can be passed directly to update_index.

The next step is to remove the creation of the table_name and foreign_key variables from the update_index method and move them into the ObserverSearchData class.

The update_index method looks like the gist below…

The code is in much better shape now, but the update_index still knows too much about what it needs to do. To take care of this we move the update_index method from SearchObserver to ObserverSearchData and make the necessary changes.

The SearchObserver class now looks like the gist below.

Now that we only have the after_save method in SearchObserver, we can turn our attention to the type checking and logic that builds each of the search_data variables.  A better home for each of these is in the model itself. In order to accomplish this, we want to create a method in each class with the same name so that we can call the method with confidence without worrying what type of object it is. After moving the logic to each controller we end up with:

The changes above allow the SearchObserver to tell the given object that it needs to update the index which is a much better design because we can now add objects in the future without having to change SearchObserver at all.  The new object would simply need to implement the update_search_data_index method with the required logic.

This refactor is an excellent example on how to make your code more confident as well as making sure that each class is better at adhering to the single responsibility principle.

There are still several more steps within each of the classes that can be performed to make this code even better. In addition, it would be better to move the tests to the spec for each model so that we don’t have to hunt down where they live in the future but for now we’re left with code that is much better than what we started with.

Extracting the InviteRedeemer class from the Invite model in Discourse – Part 3

The results of previous post left us in decent shape to finish up the refactoring of the InviteRedeemer#redeem method.  The gist below shows the starting point for this portion of the refactoring. The private methods are left out for brevity.

The first thing to tackle is the multiple assignments to the result variable.  The first change is to replace the nil assignment in ‘result = nil‘ with a call to a new method named invited_user.

By adding the method above, the else branch of the if clause can be removed. In order to make sure everything still works as expected, the tests are run and everything is green.

The second benefit of this addition is that it is no longer necessary to pass the result to the methods because the user can be retrieved from the invited_user method from the method itself.

The next step is to replace the ‘mark_invite_redeemed == 1‘ line with something that has a name that is more explanatory. To do this, a private method named invite_was_redeemed?.

After the change above, move the steps inside the if clause into their own private method named process_invitation.  

The redeem method now looks like the gist below.

At this point, things are looking really good …except for the repeated references to result. But upon taking a better look, it becomes obvious that we can rearrange things a little bit to contain all of the user retreival functionality in one place.

The changes above mean that the get_invited_user method will first check for the an existing user and then create a new user only if one doesn’t exist.

By keeping the user retrieval inside one method and combining it with the lazy initialization of invited_user, it means that we can remove result from the redeem method completely which gives us our final result.

A final check on Code Climate shows that the score for the Invite model has gone from C to A.

Image

This change was submitted to Discourse and was merged as pull request #927

Extracting the InviteRedeemer class from the Invite model in Discourse – Part 2

In the previous post, the InviteRedeemer struct was extracted in order to isolate the functionality required to redeem an invite.  When we left off, the redeem method had been moved to InviteRedeemer and all the tests were passing which gives the assurance that we have preserved all of the functionality required.

The starting point for the next steps are based around the comments within the method.  Each highlights different pieces of functionality that can be split out into a private method with a name that is indicative of its responsibility. I started by extracting a private method for each of the actions marked by a comment.

At this point, InviteRedeemer looks better because we can see that there are very procedural steps to what is happening but there are still many things that need to be corrected.

The multiple assignments to the result variable as well as the number of times result is passed around shows us that there’s still a lot of work to be done.

One thing it does do is to make the next step of cleaning up the row_count assignment and comparison a little easier to see.  The result of this step is shown below.

This still looks a little weird with the result of the update being checked to see if it is equal to one, but we will deal with that in the next post.