For the past few lessons now, we've been making use of the wc
command as a point of reference in order to gain inspiration about the behaviour and features of our own word counter application.
If you'll recall, every time that I used the wc
command I was passing in the following -w
argument, typically before passing in the txt file that I wanted to count. This command line argument of -w
is actually what's known as a CLI flag, and is used in order to control the behaviour of the wc
command. In this case, it's constraining the wc
command to only count the number of words, with the -w
representing words.
However, if I go ahead and remove this flag, instead just passing in the words.txt
, you'll notice this time I actually get three different numbers back. The 5
here is the number of words, which we know from the wc -w
command. However, it may be a little elusive as to what the other two numbers represent. If we take a look at the manual for the wc
command, which is done by typing in the command of man wc
(man
standing for manual), you can see in the description that it's letting us know that we're printing the newline, word and byte counts for each file, and a total line if more than one file is specified, which we're already doing.
This means the first count in our wc
output is the number of newlines, the number of words as we know, and the number of bytes. Therefore, in the case of our words.txt
, you can see the number of newlines is 1
, the number of words is 5
, and the number of bytes is 26
. In the case of our counter, we're only printing out the number of words, as you can see as follows. However, it would be nice if we could have similar behaviour to the wc
command, where we also print out the number of lines, as well as the number of bytes. Additionally, being able to control these using CLI flags, which are a specialised version of command line arguments, allowing you to change the behaviour of your applications.
Therefore, in our case, let's go ahead and spend the next few lessons implementing each of these three features, adding in the ability to count the number of lines and number of bytes, as well as being able to control them using the various options. For example, the wc -l
command will only print out the number of lines, the wc -c
command will only print out the number of bytes, and the wc -w
command, which I've been using before, will print out the number of words. Additionally, you can constrain these, so we're only printing out the number of lines and bytes using -l
and -c
.
Additionally, we can also combine flags when it comes to the wc
command, such as passing in -w
and -l
in order to get the number of words and lines, or passing in -c -l
to get the number of lines and bytes. You'll notice that the order is still the same, however, with lines taking precedence, then words, then bytes. By adding these features, it'll not only teach us how we can add more functionality into our command line application, but it will also teach us how we can make use of CLI flags in order to control options when it comes to our application code.
Therefore, to begin, let's go ahead and get set up so that we can start adding in these new features.
Therefore, in order to begin, we're going to spend the remainder of this lesson doing some slight refactoring of our code, just to make it a little bit easier to understand what is actually going on. To do so, let's go ahead and create a new file inside of our project called count.go
, which is going to contain all of our counting code. Inside, let's go ahead and set the package to be main
as it's part of the main package, and we then want to go ahead and pull out some of the code from our main.go
function. In this case, we want to pull out the countWordsInFile
and countWords
functions and place them inside of this new file.
We're also going to need to add in our imports, which are the os
package, the io
package, and the bufio
package as well. Then we can remove these imports inside of our main.go
function.
With that, we should just now have only our main function inside of the main.go
file, and inside of our count.go
file, we should have our countWordsInFile
function, and our countWords
function as well. Lastly, let's go ahead and rename the main_test.go
file to be the count_test.go
file, as it now relates to the code inside of the count.go
file.
With that, our code is now just a little bit easier to understand where it is, and we're ready to begin making some more changes in order to make this code work with our new features. In any case, now's a good time to go ahead and commit this code as follows, adding in both the count.go
, count_test.go
, and the changes from the main.go
and main_test.go
as follows, and your git status
should look very similar to mine, with the count.go
file as a new file, and renaming the main_test.go
to count_test.go
as well as modifying the main.go
file.
With those changes made, let's go ahead and commit them. Initial work for refactor, and adding features, adding lines and byte features. And with that, we're ready to move on to our next lesson, where we're going to implement the line counting algorithm.