- •Programming Ruby The Pragmatic Programmer's Guide
- •Foreword
- •Preface
- •Ruby Sparkles
- •What Kind of Language Is Ruby?
- •Is Ruby for Me?
- •Why Did We Write This Book?
- •Ruby Versions
- •Installing Ruby
- •Building Ruby
- •Running Ruby
- •Interactive Ruby
- •Ruby Programs
- •Resources
- •Acknowledgments
- •Notation Conventions
- •Roadmap
- •Ruby.New
- •Ruby Is an Object-Oriented Language
- •Some Basic Ruby
- •Arrays and Hashes
- •Control Structures
- •Regular Expressions
- •Blocks and Iterators
- •Reading and 'Riting
- •Onward and Upward
- •Classes, Objects, and Variables
- •Inheritance and Messages
- •Inheritance and Mixins
- •Objects and Attributes
- •Writable Attributes
- •Virtual Attributes
- •Class Variables and Class Methods
- •Class Variables
- •Class Methods
- •Singletons and Other Constructors
- •Access Control
- •Specifying Access Control
- •Variables
- •Containers, Blocks, and Iterators
- •Containers
- •Implementing a SongList Container
- •Blocks and Iterators
- •Implementing Iterators
- •Blocks for Transactions
- •Blocks Can Be Closures
- •Standard Types
- •Numbers
- •Strings
- •Working with Strings
- •Ranges as Sequences
- •Ranges as Conditions
- •Ranges as Intervals
- •Regular Expressions
- •Patterns
- •Anchors
- •Character Classes
- •Repetition
- •Alternation
- •Grouping
- •Pattern-Based Substitution
- •Backslash Sequences in the Substitution
- •Object-Oriented Regular Expressions
- •More About Methods
- •Defining a Method
- •Variable-Length Argument Lists
- •Methods and Blocks
- •Calling a Method
- •Expanding Arrays in Method Calls
- •Making Blocks More Dynamic
- •Collecting Hash Arguments
- •Expressions
- •Operator Expressions
- •Miscellaneous Expressions
- •Command Expansion
- •Backquotes Are Soft
- •Assignment
- •Parallel Assignment
- •Nested Assignments
- •Other Forms of Assignment
- •Conditional Execution
- •Boolean Expressions
- •Defined?, And, Or, and Not
- •If and Unless Expressions
- •If and Unless Modifiers
- •Case Expressions
- •Iterators
- •Break, Redo, and Next
- •Variable Scope and Loops
- •Exceptions, Catch, and Throw
- •The Exception Class
- •Handling Exceptions
- •Tidying Up
- •Play It Again
- •Raising Exceptions
- •Adding Information to Exceptions
- •Catch and Throw
- •Modules
- •Namespaces
- •Instance Variables in Mixins
- •Iterators and the Enumerable Module
- •Including Other Files
- •Basic Input and Output
- •What Is an io Object?
- •Opening and Closing Files
- •Reading and Writing Files
- •Iterators for Reading
- •Writing to Files
- •Talking to Networks
- •Threads and Processes
- •Multithreading
- •Creating Ruby Threads
- •Manipulating Threads
- •Thread Variables
- •Threads and Exceptions
- •Controlling the Thread Scheduler
- •Mutual Exclusion
- •The Mutex Class
- •Condition Variables
- •Running Multiple Processes
- •Spawning New Processes
- •Independent Children
- •Blocks and Subprocesses
- •When Trouble Strikes
- •Ruby Debugger
- •Interactive Ruby
- •Editor Support
- •But It Doesn't Work!
- •But It's Too Slow!
- •Create Locals Outside Blocks
- •Use the Profiler
- •Ruby and Its World
- •Command-Line Arguments
- •Command-Line Options
- •Program Termination
- •Environment Variables
- •Writing to Environment Variables
- •Where Ruby Finds Its Modules
- •Build Environment
- •Ruby and the Web
- •Writing cgi Scripts
- •Using cgi.Rb
- •Quoting
- •Creating Forms and html
- •Cookies
- •Sessions
- •Embedding Ruby in html
- •Using eruby
- •Installing eruby in Apache
- •Improving Performance
- •Ruby Tk
- •Simple Tk Application
- •Widgets
- •Setting Widget Options
- •Getting Widget Data
- •Setting/Getting Options Dynamically
- •Sample Application
- •Binding Events
- •Scrolling
- •Just One More Thing
- •Translating from Perl/Tk Documentation
- •Object Creation
- •Running Ruby Under Windows
- •Windows Automation
- •Getting and Setting Properties
- •Named Arguments
- •For each
- •An Example
- •Optimizing
- •Extending Ruby
- •Ruby Objects in c
- •Value as a Pointer
- •Value as an Immediate Object
- •Writing Ruby in c
- •Evaluating Ruby Expressions in c
- •Sharing Data Between Ruby and c
- •Directly Sharing Variables
- •Wrapping c Structures
- •An Example
- •Memory Allocation
- •Creating an Extension
- •Creating a Makefile with extconf.Rb
- •Static Linking
- •Embedding a Ruby Interpreter
- •Bridging Ruby to Other Languages
- •Ruby c Language api
- •The Ruby Language
- •Source Layout
- •Begin and end Blocks
- •General Delimited Input
- •The Basic Types
- •Integer and Floating Point Numbers
- •Strings
- •Requirements for a Hash Key
- •Symbols
- •Regular Expressions
- •Regular Expression Options
- •Regular Expression Patterns
- •Substitutions
- •Extensions
- •Variable/Method Ambiguity
- •Variables and Constants
- •Scope of Constants and Variables
- •Predefined Variables
- •Exception Information
- •Pattern Matching Variables
- •Input/Output Variables
- •Execution Environment Variables
- •Standard Objects
- •Global Constants
- •Expressions Single Terms
- •Operator Expressions
- •More on Assignment
- •Parallel Assignment
- •Block Expressions
- •Boolean Expressions
- •Truth Values
- •And, Or, Not, and Defined?
- •Comparison Operators
- •Ranges in Boolean Expressions
- •Regular Expressions in Boolean Expressions
- •While and Until Modifiers
- •Break, Redo, Next, and Retry
- •Method Definition
- •Method Arguments
- •Invoking a Method
- •Class Definition
- •Creating Objects from Classes
- •Class Attribute Declarations
- •Module Definitions
- •Mixins---Including Modules
- •Module Functions
- •Access Control
- •Blocks, Closures, and Proc Objects
- •Proc Objects
- •Exceptions
- •Raising Exceptions
- •Handling Exceptions
- •Retrying a Block
- •Catch and Throw
- •Classes and Objects
- •How Classes and Objects Interact
- •Your Basic, Everyday Object
- •Object-Specific Classes
- •Mixin Modules
- •Extending Objects
- •Class and Module Definitions
- •Class Names Are Constants
- •Inheritance and Visibility
- •Freezing Objects
- •Locking Ruby in the Safe
- •Safe Levels
- •Tainted Objects
- •Reflection, ObjectSpace, and Distributed Ruby
- •Looking at Objects
- •Looking Inside Objects
- •Looking at Classes
- •Looking Inside Classes
- •Calling Methods Dynamically
- •Performance Considerations
- •System Hooks
- •Runtime Callbacks
- •Tracing Your Program's Execution
- •How Did We Get Here?
- •Marshaling and Distributed Ruby
- •Custom Serialization Strategy
- •Distributed Ruby
- •Compile Time? Runtime? Anytime!
- •Standard Library
The Basic Types
The basic types in Ruby are numbers, strings, arrays, hashes, ranges, symbols, and regular expressions.
Integer and Floating Point Numbers
Ruby integers are objects of class FixnumorBignum.Fixnumobjects hold integers that fit within the native machine word minus 1 bit. Whenever aFixnumexceeds this range, it is automatically converted to aBignumobject, whose range is effectively limited only by available memory. If an operation with aBignumresult has a final value that will fit in aFixnum, the result will be returned as aFixnum.
Integers are written using an optional leading sign, an optional base indicator (0for octal,0xfor hex, or0bfor binary), followed by a string of digits in the appropriate base. Underscore characters are ignored in the digit string.
You can get the integer value corresponding to an ASCII character by preceding that character with a question mark. Control and meta combinations of characters can also be generated using ?\C-x, ?\M-x, and ?\M-\C-x. The control version ofchisch&0x9f, and the meta version isch | 0x80. You can get the integer value of a backslash character using the sequence?\\.
123456 # Fixnum 123_456 # Fixnum (underscore ignored) -543 # Negative Fixnum 123_456_789_123_345_789 # Bignum 0xaabb # Hexadecimal 0377 # Octal -0b1010 # Binary (negated) 0b001_001 # Binary ?a # character code ?A # upper case ?\C-a # control a = A - 0x40 ?\C-A # case ignored for control chars ?\M-a # meta sets bit 7 ?\M-\C-a # meta and control a |
A numeric literal with a decimal point and/or an exponent is turned into a Floatobject, corresponding to the native architecture'sdoubledata type. You must follow the decimal point with a digit, as1.e3tries to invoke the methode3in classFixnum.
12.34 |
» |
12.34 |
-.1234e2 |
» |
-12.34 |
1234e-2 |
» |
12.34 |
Strings
Ruby provides a number of mechanisms for creating literal strings. Each generates objects of type String. The different mechanisms vary in terms of how a string is delimited and how much substitution is done on the literal's content.
Single-quoted string literals ('stuff'and %q/stuff/) undergo the least substitution. Both convert the sequence into a single backslash, and the form with single quotes converts \' into a single quote.
'hello' |
» |
hello |
'a backslash \'\\\'' |
» |
a backslash '\' |
%q/simple string/ |
» |
simple string |
%q(nesting (really) works) |
» |
nesting (really) works |
%q no_blanks_here ; |
» |
no_blanks_here |
Double-quoted strings ("stuff", %Q/stuff/, and %/stuff/) undergo additional substitutions, shown in Table 18.2 on page 203.
Substitutions in double-quoted strings
|
a = 123 | ||
"\123mile" |
» |
Smile |
"Say \"Hello\"" |
» |
Say "Hello" |
%Q!"I said 'nuts'," I said! |
» |
"I said 'nuts'," I said |
%Q{Try #{a + 1}, not #{a - 1}} |
» |
Try 124, not 122 |
%<Try #{a + 1}, not #{a - 1}> |
» |
Try 124, not 122 |
"Try #{a + 1}, not #{a - 1}" |
» |
Try 124, not 122 |
Strings can continue across multiple input lines, in which case they will contain newline characters. It is also possible to use here documentsto express long string literals. Whenever Ruby parses the sequence <<identifieror <<quoted string, it replaces it with a string literal built from successive logical input lines. It stops building the string when it finds a line that starts with the identifier or thequoted string. You can put a minus sign immediately after the << characters, in which case the terminator can be indented from the left margin. If a quoted string was used to specify the terminator, its quoting rules will be applied to the here document; otherwise, double-quoting rules apply.
a = 123 print <<HERE Double quoted \ here document. Sum = #{a + 1} HERE
print <<-'THERE' This is single quoted. The above used #{a + 1} THERE |
produces:
Double quoted here document. Sum = 124 This is single quoted. The above used #{a + 1} |
Adjacent single- and double-quoted strings in the input are concatenated to form a single Stringobject.
'Con' "cat" 'en' "ate" |
» |
"Concatenate" |
Strings are stored as sequences of 8-bit bytes,[For use in Japan, the jcode library supports a set of operations of strings written with EUC, SJIS, or UTF-8 encoding. The underlying string, however, is still accessed as a series of bytes.]and each byte may contain any of the 256 8-bit values, including null and newline. The substitution mechanisms in Table 18.2 on page 203 allow nonprinting characters to be inserted conveniently and portably.
Every time a string literal is used in an assignment or as a parameter, a new Stringobject is created.
for i in 1..3 print 'hello'.id, " " end |
produces:
537763324 537763034 537763004 |
The documentation for class Stringstarts on page 363.
Ranges
Outside the context of a conditional expression, expr..exprandexpr...exprconstructRangeobjects. The two-dot form is an inclusive range; the one with three dots is a range that excludes its last element. See the description of classRangeon page 359 for details. Also see the description of conditional expressions on page 222 for other uses of ranges.
Arrays
Literals of class Arrayare created by placing a comma-separated series of object references between square brackets. A trailing comma is ignored.
arr = [ fred, 10, 3.14, "This is a string", barney("pebbles"), ] |
Arrays of strings can be constructed using a shortcut notation, %w, which extracts space-separated tokens into successive elements of the array. A space can be escaped with a backslash. This is a form of general delimited input, described on pages 200--201.
arr = %w( fred wilma barney betty great\ gazoo ) | ||
arr |
» |
["fred", "wilma", "barney", "betty", "great gazoo"] |
Hashes
A literal Ruby Hashis created by placing a list of key/value pairs between braces, with either a comma or the sequence=>between the key and the value. A trailing comma is ignored.
colors = { "red" => 0xf00, "green" => 0x0f0, "blue" => 0x00f } |
There is no requirement for the keys and/or values in a particular hash to have the same type.