Note: For a more complete Ruby
tutorial, download Huw's free eBook (and source code), The
Little Book Of Ruby, from SapphireSteel Software. |
See also: Part
One and Part Two of this series
|
|
Note:
You can download all
the Ruby programs used in this column and run them
either from the command prompt or via an editor/IDE.
The screenshots in this article show an early beta
of Ruby In Steel 'Personal Edition' – a
free Ruby IDE for Visual Studio 2005. The final version
of Ruby In Steel PE 1.0 was released after this article
was published. A commercial edition of Ruby In Steel
('Developer Edition') has also been released, which
includes the ultra-fast 'Cylon' debugger and powerful
analytical IntelliSense capabilities.
To download, evaluate or buy Ruby
In Steel, go to the SapphireSteel Software
site: http://www.sapphiresteel.com |
As I mentioned back in part one of this series, double-quoted
strings do more work than single-quoted strings. In particular,
they have the ability to evaluate bits of themselves
as though they were programming code. Here is an example
from one of this month’s sample programs, 1strings.rb:
myname = 'Fred'
puts( 'Hello #{myname}' )
puts( "Hello #{myname}" )
In the example above, #{myname} in the double-quoted
string tells Ruby to evaluate the myname variable and
insert its value into the string itself. So, if myname equals “Fred”, the string “Hello
Fred” will
be displayed. No evaluation is done in a single-quoted
string, however, which is why this type of string displays
the actual characters entered: ‘Hello #{myname}’.
A double-quoted string is also able to evaluate variables
and attributes (‘properties’) such as ob.name,
expressions such as 2*3 and bits of code such as the
method-call ob.ten and ‘escape characters’ such
as “\n” and “\t” representing
a newline and a tab. Once again, a single-quoted string
does no such evaluation. A single-quoted string can,
however, use a backslash to indicate that the next character
should be treated literally. This is useful when a single-quoted
string contains a single-quote character, like this:
‘It\’s my party’
User-Defined String Delimiters
If, for some reason, single and double-quotes aren’t
convenient – if, for example, your strings contain
lots of quote characters and you don’t want to
have to keep putting backslashes in front of them – you
have the option of delimiting strings in many other ways. See 2strings.rb for
some examples.
The standard alternative delimiters for double quoted
strings are %Q and / or %/ and / while for single-quoted
strings they are %q and /. Thus…
%Q/This is the same as a double-quoted string./
%/This is also the same as a double-quoted string./
%q/And this is the same as a single-quoted string/
You can even define your own string delimiters. These
must be non-alphanumeric characters and they may even
be non-printing characters such as newlines or characters
which normally have a special meaning in Ruby such as
the ‘pound’ or ‘hash’ (#).
Whichever character you choose, it should be placed
after %q or %Q and you should be sure to terminate the
string with the same character. If your delimiter is
an opening bracket, the corresponding closing bracket
should be used at the end of the string, like this:
%Q[Hello #{myname}]
puts( %q+Hello #{myname}+ )
You will find examples of a broad range of user-selected
string delimiters in the sample program, 3strings.rb.
Needless to say, while there may be times when it is
useful to delimit a string by some esoteric character
such as a newline or an asterisk, in many cases the disadvantages
(not least the mental anguish and confusion) resulting
from such arcane practices may significantly outweigh
the advantages.
Backquotes
One other type of string deserves a special mention:
namely, strings enclosed by back-quotes – that
is, the inward-pointing quote character which is usually
tucked away up towards the top left-hand corner of the
keyboard: `
Ruby considers anything enclosed by back-quotes to be
a command which can be passed for execution by the operating
system using a method such as print or puts. By now,
you will probably already have guessed that (as with
so many things) Ruby provides more than one way of doing
this. It turns out %/some
command/ has the same effect
as `somecommand` and so does %x{some
command}. On the
Windows operating system, for example, each of the three
lines shown below would pass the command dir to the operating
system, causing a directory listing to be displayed:
puts(`dir`)
puts(%x/dir/)
puts(%x{dir})
You can also embed commands inside double-quoted strings
like this:
print( "Goodbye #{%x{calc}}" )
Be careful if you do this. The command itself is evaluated
first. Your Ruby program then waits until the process
which starts has terminated. In the present case, the
calculator will pop up. You are now free to do some calculations,
if you wish. Only when you close the calculator will
the string “Goodbye” be displayed. The program, 4backquotes.rb,
provides a few more examples.
Using backquoted strings you can run operating system
commands or start external applications. Here.
for example, we have started up the Windows Notepad. |
String Handling
Let’s take a quick look at a few common string
operations.
Concatenation
You can concatenate strings using << or + or just
by placing a space between them (see: string_concat.rb).
Here are three examples of string concatenation; in each
case, s is assigned the string “Hello World”:
s = "Hello " << "world"
s = "Hello " + "world"
s = "Hello " "world"
Refer to the comments in the source code for more information
on these operations.
String Assignment
The Ruby String class provides a number of useful string
handling methods. Most of these methods create
and return new string objects. So, for example, in the
following code, the s on
the left-hand side of the assignment on the second line
is not the same object as the s on
the right-hand side:
s = "Hello world"
s = s + "!"
A few string methods alter the string itself without
creating a new object. These methods generally end with
an exclamation mark (e.g. the capitalize! method). In
fact, the << concatenation
method which I mentioned earlier also modifies the receiver
object (the string to its left). Watch out for this!
If in doubt, you can check an object’s identity
using the object_id method. I’ve provided a few
examples of operations which do and do not create new
strings in the string_assign.rb program.
Run this and check the object_id of s after each string
operation is performed.
Indexing Into A String
You can treat a string as an array of characters and
index into that array to find a character at a specific
index using square brackets. Strings and arrays in Ruby
are indexed from 0 (the first character). So, for instance,
to replace the character ‘e’ with ‘a’ in
the string, s, which currently contains ‘Hello
world’, you would assign a new character to index
1:
s[1] = 'a'
However, if you index into a string in order to find
a character at a specific location, Ruby doesn’t
return the character itself; it returns its ASCII value:
s = "Hello world"
puts( s[1] )
In order to obtain the actual character, you can do
this:
s = "Hello world"
puts( s[1,1] )
This tells Ruby to index into the string at position
1 and return one character. If you want to return three
characters starting at position 1, you would enter this:
puts( s[1,3] )
This tells Ruby to start at position 1 and return the
next 3 characters. Alternatively, you could use the two-dot ‘range’ notation:
puts( s[1..3] )
Strings can also be indexed using minus values, in which
case -1 is the index of the last character and, once
again, you can specify the number of characters to be
returned:
puts( s[-1,1] )
puts( s[-5,1] )
puts( s[-5,5] )
When specifying ranges using a minus index (see: string_index.rb),
you must use minus values for both the start and end
indices:
puts( s[-5..5] )
puts( s[-5..-1] )
Finally, you may want to experiment with a few of the
standard methods available for manipulating strings.
These include methods to change the case of a string,
reverse it, insert substrings, remove repeating characters
and so on. I’ve provided a few examples in string_methods.rb.
If you want to mangle the works of Shakespeare, a few
of Ruby's string handling methods will do the job
nicely! |
Chop and chomp…
A couple of handy string processing methods deserve
special mention. The chop and chomp methods can be used
to remove characters from the end of a string. The chop method returns a string with the last character removed
or with the carriage return and newline characters removed
(“\r\n”) if these are found at the end of
the string. The chomp method returns a string with the
terminating carriage return or newline character removed
(or both the carriage return and the newline
character if both are found). Run the chop_chomp.rb program
to see these in use.
The Record Separator -
$/
Ruby pre-defines a variable, $/, as a ‘record
separator’. This variable is used by methods
such as gets and chomp. The gets method reads in
a string up to and including the record separator.
The chomp method returns a string with the record
separator removed from the end (if present) otherwise
it returns the original string unmodified. You
can redefine the record separator if you wish,
like this:
$/=”*”
When you redefine the record separator, this new
character (or string ) will now be used by methods
such as gets and chomp. For example:
$/= “world”
s = gets()
puts( s ) |
These methods are useful when you need to removing line
feeds entered by the user or read from a file. For instance,
when you use gets to read in a line of text, it returns
the line including the terminating ‘record separator’ which,
by default, is the newline character. You can remove
the newline character using either chop or chomp. In
most cases, chomp is preferable as it won’t remove
the final character unless it is the record separator
(a newline) whereas chop will remove the last character
no matter what it is. Here are some examples:
s1 = "Hello world
"
s2 = "Hello world"
s1.chop
s1.chomp
s2.chop
s2.chomp
The chomp method also lets you specify a character or
string to use as the separator:
s2.chomp(‘rld’)
Format Strings
Ruby provides the printf method to print ‘format
strings’ containing special field specifiers starting
with a percent sign (see: string_printf.rb).
The format string may be followed by one or more data
items separated by commas; the list of data items should
match the number and type of the format specifiers. The
actual data items replace the matching specifiers in
the string and they are formatted accordingly.
These are some common formatting specifiers:
%d – decimal number
%f – floating point number
%o – octal number
%p – inspect object
%s – string
%x – hexadecimal number
You can control floating point precision by putting
a point-number before the floating point formatting specifier,
%f. For example, this would display the floating point
value to two digits:
printf( “%0.02f”, 10.12945 )
|
|
|
Well, that just about
wraps up this introduction to Ruby programming. However,
if it’s whetted your appetite for the language,
fear not – we’ll have more Ruby coverage
in future issues…! |
April 2006 |