
- •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
Substitutions
#{...}
Performs an expression substitution, as with strings. By default, the substitution is performed each time a regular expression literal is evaluated. With the /ooption, it is performed just the first time.
\0, \1, \2, ... \9, \&, \`, \', \+
Substitutes the value matched by the nth grouped subexpression, or by the entire match, pre- or postmatch, or the highest group.
Extensions
In common with Perl and Python, Ruby regular expressions offer some extensions over traditional Unix regular expressions. All the extensions are entered between the characters (?and). The parentheses that bracket these extensions are groups, but they do not generate backreferences: they do not set the values of\1and$1etc.
(?# comment)
Inserts a comment into the pattern. The content is ignored during pattern matching.
(?:re)
Makes reinto a group without generating backreferences. This is often useful when you need to group a set of constructs but don't want the group to set the value of$1or whatever. In the example that follows, both patterns match a date with either colons or spaces between the month, day, and year. The first form stores the separator character in$2and$4, while the second pattern doesn't store the separator in an external variable.
-
date = "12/25/01"
date =~ %r{(\d+)(/|:)(\d+)(/|:)(\d+)}
[$1,$2,$3,$4,$5]
»
["12", "/", "25", "/", "01"]
date =~ %r{(\d+)(?:/|:)(\d+)(?:/|:)(\d+)}
[$1,$2,$3]
»
["12", "25", "01"]
(?=re)
Matches reat this point, but does not consume it (also known charmingly as ``zero-width positive lookahead''). This lets you look forward for the context of a match without affecting$&. In this example, thescanmethod matches words followed by a comma, but the commas are not included in the result.
-
str = "red, white, and blue"
str.scan(/[a-z]+(?=,)/)
»
["red", "white"]
(?!re)
Matches if redoes not match at this point. Does not consume the match (zero-width negative lookahead). For example,/hot(?!dog)(\w+)/matches any word that contains the letters ``hot'' that aren't followed by ``dog'', returning the end of the word in$1.
(?>re)
Nests an independent regular expression within the first regular expression. This expression is anchored at the current match position. If it consumes characters, these will no longer be available to the higher-level regular expression. This construct therefore inhibits backtracking, which can be a performance enhancement. For example, the pattern /a.*b.*a/takes exponential time when matched against a string containing an ``a'' followed by a number of ``b''s, but with no trailing ``a.'' However, this can be avoided by using a nested regular expression/a(?>.*b).*a/. In this form, the nested expression consumes all the the input string up to the last possible ``b'' character. When the check for a trailing ``a'' then fails, there is no need to backtrack, and the pattern match fails promptly.
-
require "benchmark"
include Benchmark
str = "a" + ("b" * 5000)
bm(8) do |test|
test.report("Normal:") { str =~ /a.*b.*a/ }
test.report("Nested:") { str =~ /a(?>.*b).*a/ }
end
produces:
-
user system total real
Normal: 4.170000 0.000000 4.170000 ( 4.150970)
Nested: 0.000000 0.000000 0.000000 ( 0.001529)
(?imx)
Turns on the corresponding ``i,'' ``m,'' or ``x'' option. If used inside a group, the effect is limited to that group.
(?-imx)
Turns off the ``i,'' ``m,'' or ``x'' option.
(?imx:re)
Turns on the ``i,'' ``m,'' or ``x'' option for re.
(?-imx:re)
Turns off the ``i,'' ``m,'' or ``x'' option for re.
Names
Ruby names are used to refer to constants, variables, methods, classes, and modules. The first character of a name helps Ruby to distinguish its intended use. Certain names, listed in Table 18.3 on page 210, are reserved words and should not be used as variable, method, class, or module names.
Reserved words
|
In these descriptions, lowercase lettermeans the characters ``a'' though ``z'', as well as ``_'', the underscore.Uppercase lettermeans ``A'' though ``Z,'' anddigitmeans ``0'' through ``9.''Name charactersmeans any combination of upper- and lowercase letters and digits.
A local variable name consists of a lowercase letter followed by name characters.
fred anObject _x three_two_one |
An instance variable name starts with an ``at'' sign (``@'') followed by an upper- or lowercase letter, optionally followed by name characters.
@name @_ @Size |
A class variable name starts with two ``at'' signs (``@@'') followed by an upper- or lowercase letter, optionally followed by name characters.
@@name @@_ @@Size |
A constant name starts with an uppercase letter followed by name characters. Class names and module names are constants, and follow the constant naming conventions. By convention, constant variables are normally spelled using uppercase letters and underscores throughout.
module Math PI = 3.1415926 end class BigBlob |
Global variables, and some special system variables, start with a dollar sign (``$'') followed by name characters. In addition, there is a set of two-character variable names in which the second character is a punctuation character. These predefined variables are listed starting on page 213. Finally, a global variable name can be formed using ``$-'' followed byanysingle character.
$params $PROGRAM $! $_ $-a $-. |
Method names are described in the section beginning on page 225.