During development, it’s common to view and edit the same group of related files, to navigate the same classes, and to run and rerun the same tests. An IDE that keeps track of recent activities can help simplify performing these types of repetitive development tasks. In this post, we’ll look at how to view and re-execute recent activities in RubyMine on OS X.
So you have a team of four developers and a product manager. You seem to be in a good place: you’re using Pivotal Tracker to keep visibility into your backlog of work, your velocity is high and, more importantly, constant. Releases went well and the team you’ve built can efficiently mutate your software to suit every new product idea. It’s a proven recipe for success!
But now you have some more money and want to go faster. You decide that you need to grow the team. You add two more pairs in the hope of getting twice as much done.
Two months down the line, you realise things aren’t going quite as fast as predicted. Developers are treading on each other’s toes and build time is rapidly increasing because lots of slow high-level (or even slow unit-level) tests are being added. You need a solution to these problems, and you decide to mitigate developer work clashes and accidental double-work by carving the backlog into ‘tracks’. Instead of developers working on stories as they go, by picking them off the top of the backlog, work is allocated according to clearly defined areas of the system that you believe are separate enough to avoid people bumping into each other.
These techniques seem to solve the immediate problems you’re facing. It’s another winning formula, so you add another two pairs, bringing you up to six. Now you can really rip through features!
New problems arise. Now the build is really slow, and developers choose to run subsections of the test suite before a check-in. Long periods of red builds result. The incremental stories are feeding this problem: one pair covers their behinds with high-level tests, and the pair responsible for the connecting story is so busy working out how their piece fits into the puzzle that they don’t have the mental space to hunt down and extend the previous pair’s test. You have two or more high-level tests for the same feature, and duplicate implementations of components. Nobody has visibility into this, because everybody is busy working out what their story means, or is busy implementing it. The new developers on the team are busy enough working out how the product works.
It no longer makes sense for developers to look at the backlog of work, because it’s meaningless to them: on a given day, a pair is assigned to work on a specific track, so they look at the stories labeled as such.
What happens next? The above situation either continues, gets worse, or it improves. The latter only happens if something changes. Next up, you try to split the team.
The whole team wants this, but there are forces against it: emotional ties within the team, worries about practicality, and no obvious place to split in the code. Everything was previously developed with the assumption that everyone understood all components of the system.
Eventually a split occurs anyway. Meetings are a lot shorter, and it feels easy to go back to iterative stories. Now, however, there’s not enough synchronization and the two teams are still working on the same code.
If you’re reading this thinking that I have some solutions to these problems, you’re wrong. Assuming that there is an alternative strategy, what is it? Do we enforce large stories to avoid the ‘incremental story’ problems described above? Is more architecture up-front needed to predict required team splits? Perhaps the issues I’ve described are natural and unavoidable consequences of going fast. Perhaps Fred Brooks is still right, even given the sophisticated team organisational structures we have now.
Can we go fast and keep control?
Refactoring is the process of changing the internal structure of code without changing its external behavior. Successful refactorings involve taking very small, sometimes tedious, steps. Fortunately, many refactorings are simple enough to be automated. In this post, we’ll look at automated refactorings in RubyMine on OS X.
When the name of a variable, method, or class doesn’t explain its purpose, rename it with
shift + F6.
Help explain complex expressions by introducing variables with
command + option + V.
Move related logic into a separate method with
command + option + M.
Inline Variable or Method
Inline variables and methods that don’t increase clarity with
command + option + N
Less frequently used refactorings, such as extracting a superclass or module, are available from the “Refactor This…” dialog,
control + T.
Automation Makes a Difference
Refactoring is a significant part of everyday development. It’s the final step in TDD’s mantra of red, green, refactor. We often refactor inherited code to help us better understand it. Automating refactoring encourages more refactoring. If a simple class rename involves
sed, then it’s time to upgrade to an IDE.
As a long-time command-line Git user, I was hesitant to adopt RubyMine’s version control tools. But I decided to give them a try, and I’m glad I did. RubyMine’s version control tools make common Git commands more accessible and easier to execute. The addition of a GUI is great for tasks such as diffing a file, or viewing commit logs. In this post, we’ll look at performing everyday Git commands in RubyMine on OS X.
You can view a diff of all your changes from the Changes tool window.
command + 9 to open the Changes tool window. Then press
command + D to view a diff of all your changes.
You can diff a single file by selecting “Compare with the Same Repository Version” from the VCS Operations popup. Press
control + V to open the VCS Operations popup.
command + K to commit changes.
Select “Push…” from the VCS Operations popup,
control + V, to push your local changes.
command + T to pull in the latest changes.
To view the Git log, open the Changes tool window,
command + 9, then navigate to the Log tab with
command + shift + ].
To see the log of a single file, select “Show History” from the VCS Operations popup,
control + V.
This will open the log in the Version Control tool window.
Revert changes by selecting “Revert” from the VCS Operations popup,
control + V.
Determine who changed a file by selecting “Annotate” from the VCS Operations popup,
control + V.
The committers will be displayed to the left of the editor gutter.
Don’t Abandon the Command-line
In this post, I focused on the most commonly used Git commands. RubyMine also includes support for more powerful Git commands, such as
git-rebase. However, I find their RubyMine GUI-based implementations slow and clumsy. As much as I want to stay in RubyMine, I find the best version control strategy is to use RubyMine for common Git commands, but turn to the command-line for the hard stuff.
RubyMine’s editor is tab-based. When you open a file, it’s opened in a new tab. The editor can also be split vertically or horizontally; allowing you to edit multiple files simultaneously. In this post, we’ll look at managing and navigating these basic RubyMine concepts on OS X.
Navigating Between Tabs
Move between multiple tabs with
command + shift + [/] or
control + Left/Right.
Close a tab with
command + W.
There are several other useful tab closing commands that don’t have keyboard shortcuts. I add the following shortcuts for them:
command + shift + W– close all other tabs
command + option + W– close all tabs
command + option + control + W– close all unmodified tabs
Splitting the Editor
Edit multiple files simultaneously by splitting the editor using the “Split Vertically” or “Split Horizontally” commands (find these commands quickly with
command + shift + A, “Find Action”).
command + option + control + Up/Down shortcuts to split vertically and horizontally.
Navigating Between Splits
Move the cursor to the next split with
option + Tab. Move to the previous split with
option + shift + Tab.
The Switcher can also be used to move between splits. Use
control + Tab to open the Switcher, continue holding down
control, and then use
Tab to select an open file to navigate to.
Moving Tabs Between Splits
Use the “Move To Opposite Group” command (find this command quickly with
command + shift + A, “Find Action”) to move tabs between splits.
command + option + control + Left/Right shortcuts for this command.
Close a single split by closing all of its tabs.
Close all splits with
option + shift + X.
Master the Basics
In RubyMine, you’ll use tabs and splits all the time. Don’t hesitate to create custom shortcuts for tab and split commands that don’t have them. Efficiently managing and navigating tabs and splits from the keyboard is a fundamental, must learn RubyMine skill.
When learning how to program, you were probably taught not to copy and paste code. Typing it out manually improved your understanding of its syntax and structure. However, after learning a particular concept, repeatedly typing it becomes boring and tedious. An IDE can help you automate this process by intelligently generating boilerplate code. In this post, we’ll take a look at code generation in RubyMine on OS X.
Generating Getters and Setters
If a class has instance variables, press
command + N in the editor to generate getters, setters, or both.
After selecting what type of method to generate, RubyMine will prompt you for the instance variable to generate it for.
Generating Overridden Methods
control + O to view a list of overridable methods.
Select a method from this dialog to generate a stub for it.
Generating Surrounding Code
Surround code with conditionals and other language constructs using
command + alt/option + T.
Remove surrounding code with
command + shift + delete.
RubyMine’s intentions offer many different ways for generating and modifying code. A yellow lightbulb icon in the editor indicates that intentions are available.
alt/option + enter to view the intention. Press
enter to execute it.
Intentions can even create classes.
Use intentions to modify code e.g., converting from Ruby 1.8 to 1.9 Hash syntax or converting a string from double to single quotes.
RubyMine’s live templates are commonly known as snippets in other editors. Press
command + J to view the list of available live templates.
Live templates are more commonly inserted by typing an abbreviation and then pressing
Here’s some of my favorite live templates:
def– create an instance method
defs– create a class (singleton) method
do– create a
doo– create a
do |object| ...endblock that expects an argument
it– create an RSpec example
p– access a Rails controller’s
s– access a Rails controller’s
Once you understand a particular concept, Ruby or Rails, as a programmer, your goal should be to automate it. If you’re beginning Ruby or Rails, then I would avoid code generation in order to better familiarize yourself with the language and framework. However, if you’re a veteran Rubyist, then I see nothing wrong with automating what you already know.
RubyMine’s tool windows integrate common development tasks such as searching, debugging, and version control, into the IDE. This eliminates context switching to external tools, providing a more fluid development experience. In this post, we’ll look at some common commands for managing tool windows in RubyMine on OS X.
Opening and Closing Tool Windows
Each tool window is given a number. They can be opened or closed with
command + <number>, e.g., by default, the Project tool window is given
command + 1.
Opened tool windows are located on the bottom and sides of the IDE.
Navigating Between Tool Windows
To navigate between opened tool windows, first open the Switcher with
control + tab. Then continue holding down
control and press the number of a specific tool window.
While holding down
option to move between the Switcher’s two columns.
Navigating Between Tool Windows and the Editor
esc in a tool window to move focus to the editor. Use
F12 to move focus back to the tool window.
Closing Tool Windows
Close tool windows with
command + w. Use
shift + esc in a tool window to close it and move focus to the editor.
Close all opened tool windows and move focus to the editor with
command + shift + F12. Press it again to re-open the tool windows.
Don’t Sell Your IDE Short
Many developers insist of performing certain tasks outside their IDE. Perhaps they fear losing skills they’ve heavily invested in. For certain exceptional situations, e.g., debugging production, it’s important to know how to do these tasks without an IDE. But when it comes to day-to-day development, embrace your IDE and experiment with a new way of doing old things.
Before using RubyMine, my debugging workflow went something like this:
Why isn’t this test passing?. It should’ve passed. Let me add a few
Kernel#putscalls to see what’s going on. Hmmm, ok, it’s still failing. I’m going to need some more output. Man, these tests take forever to run. Syntax error?!. Ugh, typo…
Debugging like this isn’t fun; especially when pairing. Fortunately, RubyMine can help. RubyMine includes a standard debugger that has minimal setup and works out of the box. I still don’t enjoy debugging, but RubyMine has made it much less painful. In this post, we’ll look at debugging in RubyMine on OS X.
Add or remove breakpoints with
command + F8.
View existing breakpoints with
command + shift + F8.
Starting the Debugger
Debug the current program with
control + shift + D. This will automatically open the Debug tool window (
command + 5).
control + D to re-run the last debug session. View recent debug sessions with
control + alt/option + D.
Examining a Program
Examine variables in the Debug tool window’s variables pane.
command + N in the Debug tool window’s Watches pane to watch a specific variable.
backspace will delete a watch.
alt/option + F8 to evaluate arbitrary expressions.
control + space triggers autocompletion.
Instead of using the Debug tool window, examine a variable inline by placing your cursor on it and pressing
command + alt/option + F8.
Stepping through a Program
Step into a method with
F7. Step over a method with
F8. Step out of a method with
shift + F8.
Use your cursor as a temporary breakpoint with
alt/option + F9. Continue your debug session with
If you’re using an IDE, take time to learn its debugger. Don’t litter your code with
Kernel#puts and friends. Instead, set a breakpoint, start the debugger, examine some objects, and slowly step through your problems.
As developers, we create, update, and delete files all day long. Managing files from the command-line is one of the first skills we learned. However, constantly switching from your editor to the command-line to execute a simple file command, a command you’ve probably executed thousands of times before, is tedious and slow. Instead, stay in your editor, and let it take care of the boring stuff. In this post, we’ll look at RubyMine’s file commands on OS X.
To create a new file or directory, press
control + alt/option + N within the editor or Project tool window.
F5 within the editor or Project tool window to copy the current file.
F5 can also be used in the Project tool window to copy directories.
To create a copy of a file or directory in the current directory, press
shift + F5.
Move files and directories with
Like the previous file commands, this command works both within the editor and Project tool window.
Files and directories can be renamed in the Project tool window with
shift + F6.
Delete files and directories in the Project tool window with
To locate a file in the Project tool window, press
alt/option + F1 in the editor, and then select the Project View option, the default option, from the Select Target dialog.
Select Reveal in Finder to open the file in a new OS X Finder window.
Working with File Paths
command + alt/option + F12 to view the complete file path.
Selecting a directory will open the directory in a new OS X Finder window.
Copy the current file path to the clipboard with
command + shift + C. Copy a reference, the current relative file path and line with
command + alt/option + shift + C.
These commands are useful for when you need to work with a file on the command-line.
Relying on Abstractions
A common developer fear is that overreliance on a particular IDE’s features will cause you to forget, or maybe never learn, the underlying commands. I agree that in some cases, e.g., version control, it’s important to know what’s going on under the hood. However, these situations are rare. And when it comes to everyday commands, I’d much rather use higher-level abstractions to free me from the mundane.
A typical Rails development environment includes an editor, a terminal for running a web server, and a utility terminal for managing files, using version control, running tests, etc. During development, you’re constantly switching between your editor and these external terminals. RubyMine, an Integrated Development Environment, can eliminate this tedious back and forth workflow. In this post, we’ll learn how to run programs in RubyMine on OS X; allowing you to stay in RubyMine all day long.
To run a file, open the file in the editor or select the file in the project tool window, then press
control + shift + R. Rerun a file with
control + R.
These commands are commonly used to run test files, but they could also be used to run a simple Ruby script.
Run Tool Window
All running programs are displayed in the Run tool window. Press
command + 4 to open the Run tool window.
Stop a running program with
command + F2. Use
command + shift + [ and
command + shift + ] to navigate between multiple running programs.
In a test file, press
control + shift + R outside of any individual test to run all the tests in the file. Press
control + shift + R within an individual test to run just that test.
Open the run dialog with
control + alt/option + R. The run dialog lists recently run programs. This is useful for when you want to rerun a test you ran several tests ago.
By default, this dialog also includes commands to run a development server, and your entire test suite.
Ruby/Rails Quick List
command + option + R to open the Ruby/Rails quick list. The Ruby/Rails quick list includes several useful commands such as, starting a Rails console, and starting an IRB session.
You can run a file or a code selection in an existing IRB or Rails console with
alt/option + shift + L. View IRB history with
command + E.
Running Rake Tasks
Run a Rake task with
alt/option + R.
If a custom Rake task doesn’t appear in the list, reload Rake tasks from this dialog or the Ruby/Rails quick list (
command + alt/option + R).
Running Rails Generators
Run a Rails generator with
command + alt/option + G.
If a custom Rails generator task doesn’t appear in the list, reload Rails generators from this dialog or the Ruby/Rails quick list (
command + alt/option + R).
Take Advantage of Your IDE
IDEs increase your productivity by combining all of your development tools into one program. Frequent context switching to external tools not only slows you down, but also requires more in-depth knowledge of each tool. Try gradually replacing external tools with their IDE equivalents. Over time, your knowledge of shell command options and obscure Git commands will no longer seem very important to you.
Last week I blogged about a new project for aiding in the hunt for test pollution, Scrubber. This is a personal side project that I began recently. It’s in the very early stages, like many of my other pet projects. It’s something I’ve worked on entirely alone, though I’d also love to collaborate with others and/or pair on it.
I was going to blog this week about the latest improvements I’d made to the code, and how it was going to improve the end-user’s experience despite being a mere refactor and a minor user interface tweak. I got bored after writing the first few paragraphs, and instead got distracted by the code, refactoring and tweaking it more than was necessary. A couple of hours in, I’d totally gold-plated the code in a way that I might have deemed unacceptable whilst on client time. This made me a little angry with myself: why was I procrastinating from blogging, and was I a bad developer who’d lost the ability to work alone?
Something we’re encouraged to do at Pivotal Labs is reflect on our behavior. Thinking about my boredom and procrastination a little, I realized there was something more interesting going on. The process went a bit like this:
- Start blogging about the new features. Paste the visual output of the program into the blog post. Realize that the output didn’t meet the requirement of improving the user experience.
- Start to implement the missing parts of the feature. Spend hours enjoying the freedom to refactor, delete and re-implement with no time limit, far more than when pairing on client time.
When we pair, we have a safety net to catch us when we get distracted by neat language features or elegant implementation tricks. Our partner will often remind us that we’ve spent, say, two hours making no discernible feature changes and no improvement to maintainability of the code. When soloing, however, especially on pet projects, we are free to choose a goal for the activity. Sometimes we decide to perform code katas, but other times we don’t consciously choose a goal: the goal could become apparent during the activity itself.
So it seemed that I’d accidentally found validation in what I was doing, and a potentially more interesting blog post at the same time. I’d managed to get some programming exercise in instead of banging out a not-quite-earth-shattering new feature. Specifically, I:
- Thought like a user until it became obvious that changes were still needed. Switched to developer mode by accident.
- Allowed myself to try out several approaches to the Presenter pattern, applying them to a trivial example that would not need a presenter in ‘real world’ programming.
- Used the Introduce Null Object refactor in a situation that didn’t call for it. Yet, it felt good and might even prove useful for the project later.
- Practiced several coding techniques that might become useful in the work environment.
- Temporarily inverted my work-based insecurities about performance and timeliness, providing stress relief as an unexpected benefit of my brain switching itself off from the task at hand.
Reflection is a useful technique for improving well-being. Your mileage may vary. If you’d have preferred to read about the changes made to Scrubber this week, you can read the commit history!
In RubyMine, you can create tasks to breakdown and structure your work. A task can be a simple local task, or it can correspond to a feature, bug, or chore, in an issue-tracking system. Each task in RubyMine includes the current state of the editor, allowing you to switch between tasks and resume exactly where you left off. In this post, we’ll explore RubyMine’s tasks on OS X.
alt/option + shift + N to open the task dialog. Enter the task’s name, then press
Enter to create the task.
By default, RubyMine will clear your current context and create a new changelist.
A context is a set of opened files. Each task has an associated context. When you switch tasks, its context is automatically loaded.
To switch between tasks, use
alt/option + shift + T.
Isolating Work with Changelists
A changelist is a set of related source code changes. Each task has an associated changelist.
Changelists allow you to isolate each task’s changes. Use
command + K to commit the current task’s changelist. RubyMine will now consider the task closed, and ask if you want to delete its changelist.
Pivotal Tracker Integration
Instead of manually creating tasks, you can configure RubyMine to load tasks from Pivotal Tracker.
In project settings,
command + ,, create a new Pivotal Tracker server in the Tasks Servers section. Then add your Pivotal Tracker project id (located in the Pivotal Tracker project’s settings page) and API token.
Pivotal Tracker stories will now appear in the task dialog.
Creating a new task from a Pivotal Tracker story allows you to update the story as in-progress. However, it won’t set you as the owner of the story. Also, closing the task won’t finish the story.
Clean Context Switching
RubyMine’s tasks are well-suited for serial development. But if you constantly switch contexts, like most developers, they fall short, because switching tasks brings along committed work. If each task consists of a single commit, then this isn’t a problem. However, I prefer to commit frequently; resulting in many small, granular commits. So, in my opinion, using a distributed version control system, e.g., Git, and a branch-per-feature workflow, is a better development strategy than RubyMine’s tasks. Branches keep your work isolated from the main line of development, and it’s still possible to cleanly switch contexts.
When browsing a codebase, you often want to view the definition of a particular class, method, or variable. However, sometimes you want to do the reverse; you want to see where a particular class, method, or variable is used. Typically this involves using your editor’s text search, or a command line tool, such as
ack. Unfortunately, text searches may return false positives, such as log file data, or similarly named constructs. The problem is that you want to search code not text.
RubyMine has text search, but it also includes a powerful, code-based usage search. Usage search is smarter than text search, because RubyMine is aware of code constructs such as classes, methods, and variables. This results in a more accurate search; allowing you to quickly view and navigate actual usages. In this post, we’ll explore RubyMine’s usage search on OS X.
To find where a particular class, method, variable (instance or local), or parameter is used, place your cursor on it, and press
alt/option + F7. Results will be displayed in the Find tool window.
command + alt/option + Up/Down navigates the results. Use
F4 to jump to the source code of a particular usage.
Recent usage search results can be viewed again with
command + E.
Find Usages in File
By default, find usages is scoped to the entire project. To scope it to the current file, use
command + F7.
command + G and
command + shift + G navigate the results.
command + alt/option + F7 can be used to show usages inline. Instead of displaying usages in the Find tool window, they appear in a pop-up window.
RubyMine’s usage search demonstrates an advantage an IDE has over a text editor. By being aware of code constructs, such as classes, methods, and variables, IDEs can offer powerful tools that allow you to quickly and accurately explore a codebase.