
- •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
Requirements for a Hash Key
The only restriction for a hash key is that it must respond to the message hashwith a hash value, and the hash value for a given key must not change. This means that certain classes (such asArrayandHash, as of this writing) can't conveniently be used as keys, because their hash values can change based on their contents.
If you keep an external reference to an object that is used as a key, and use that reference to alter the object and change its hash value, the hash lookup based on that key may not work.
Because strings are the most frequently used keys, and because string contents are often changed, Ruby treats string keys specially. If you use a Stringobject as a hash key, the hash will duplicate the string internally and will use that copy as its key. Any changes subsequently made to the original string will not affect the hash.
If you write your own classes and use instances of them as hash keys, you need to make sure that either (a) the hashes of the key objects don't change once the objects have been created or (b) you remember to call the Hash#rehash method to reindex the hash whenever a key hashischanged.
Symbols
A Ruby symbol is the internal representation of a name. You construct the symbol for a name by preceding the name with a colon. A particular name will always generate the same symbol, regardless of how that name is used within the program.
:Object :myVariable |
Other languages call this process ``interning,'' and call symbols ``atoms.''
Regular Expressions
Regular expression literals are objects of type Regexp. They can be created by explicitly calling theRegexp.new constructor, or by using the literal forms, /pattern/ and%r{pattern}. The%rconstruct is a form of general delimited input (described on pages 200--201).
/pattern/ /pattern/options %r{pattern} %r{pattern}options Regexp.new( 'pattern' [,options ]) |
Regular Expression Options
A regular expression may include one or more options that modify the way the pattern matches strings. If you're using literals to create the Regexpobject, then the options comprise one or more characters placed immediately after the terminator. If you're usingRegexp.new, the options are constants used as the second parameter of the constructor.
i |
Case Insensitive. The pattern match will ignore the case of letters in the pattern and string. Matches are also case-insensitive if the global variable$=is set. |
o |
Substitute Once. Any#{...}substitutions in a particular regular expression literal will be performed just once, the first time it is evaluated. Otherwise, the substitutions will be performed every time the literal generates aRegexpobject. |
m |
Multiline Mode. Normally, ``.'' matches any character except a newline. With the/moption, ``.'' matches any character. |
x |
Extended Mode. Complex regular expressions can be difficult to read. The `x' option allows you to insert spaces, newlines, and comments in the pattern to make it more readable. |
Regular Expression Patterns
regular characters
All characters except ., |, (, ), [, \, ^, {, +, $, *, and ? match themselves. To match one of these characters, precede it with a backslash.
^
Matches the beginning of a line.
$
Matches the end of a line.
\A
Matches the beginning of the string.
\z
Matches the end of the string.
\Z
Matches the end of the string unlessthe string ends with a ``\n'', in which case it matches just before the ``\n''.
\b, \B
Match word boundaries and nonword boundaries respectively.
[ characters ]
A character class matches any single character between the brackets. The characters |, (, ), [, ^, $, *,and?, which have special meanings elsewhere in patterns, lose their special significance between brackets. The sequences\nnn,\xnn,\cx,\C-x,\M-x, and\M-\C-xhave the meanings shown in Table 18.2 on page 203. The sequences\d,\D,\s,\S,\w, and\Ware abbreviations for groups of characters, as shown in Table 5.1 on page 59. The sequence c1-c2represents all the characters between c1and c2, inclusive. Literal]or-characters must appear immediately after the opening bracket. An uparrow (^) immediately following the opening bracket negates the sense of the match---the pattern matches any character that isn't in the character class.
\d, \s, \w
Are abbreviations for character classes that match digits, whitespace, and word characters, respectively. \D, \S, and \W match characters that are not digits, whitespace, or word characters. These abbreviations are summarized in Table 5.1 on page 59.
. (period)
Appearing outside brackets, matches any character except a newline. (With the /moption, it matches newline, too).
re *
Matches zero or more occurrences of re.
re +
Matches one or more occurrences of re.
re {m,n}
Matches at least ``m'' and at most ``n'' occurrences of re.
re ?
Matches zero or one occurrence of re. The*,+, and{m,n}modifiers are greedy by default. Append a question mark to make them minimal.
re1 | re2
Matches either re1orre2.|has a low precedence.
(...)
Parentheses are used to group regular expressions. For example, the pattern /abc+/matches a string containing an ``a,'' a ``b,'' and one or more ``c''s./(abc)+/matches one or more sequences of ``abc''. Parentheses are also used to collect the results of pattern matching. For each opening parenthesis, Ruby stores the result of the partial match between it and the corresponding closing parenthesis as successive groups. Within the same pattern,\1refers to the match of the first group,\2the second group, and so on. Outside the pattern, the special variables$1,$2, and so on, serve the same purpose.