Tài liệu tự học lập trình - ruby cookbook recipes for object oriented scripting (2nd ed ) carlson richardson 2015 03 25
Trang 1Why spend time on coding problems that others have already solved when
you could be making real progress on your Ruby project? This updated
cookbook provides more than 350 recipes for solving common problems,
on topics ranging from basic data structures, classes, and objects, to web
development, distributed programming, and multithreading
Revised for Ruby 2.1, each recipe includes a discussion on why and how
the solution works You’ll find recipes suitable for all skill levels, from
Ruby newbies to experts who need an occasional reference With Ruby
Cookbook, you’ll not only save time, but keep your brain percolating with
new ideas as well
Recipes cover:
■ Data structures including strings, numbers, date and time,
arrays, hashes, files, and directories
■ Using Ruby’s code blocks, also known as closures
■ OOP features such as classes, methods, objects, and modules
■ XML and HTML, databases and persistence, and graphics and
other formats
■ Web development with Rails and Sinatra
■ Internet services, web services, and distributed programming
■ Software testing, debugging, packaging, and distributing
■ Multitasking, multithreading, and extending Ruby with other
languages
Lucas Carlson founded AppFog, a PaaS that leverages the open source Cloud
Foundry project A professional developer for 20 years, he specializes in Ruby on
Rails development Lucas has written Programming for PaaS and Ruby Cookbook,
First Edition (both O’Reilly) He maintains a website at http://www.lucascarlson.net/.
Leonard Richardson has been programming since he was eight years old
Recently, the quality of his code has improved somewhat He is responsible for
programming language libraries, including Rubyful Soup He maintains a website
Upd ate
d f
or R uby 2 1
Trang 2Why spend time on coding problems that others have already solved when
you could be making real progress on your Ruby project? This updated
cookbook provides more than 350 recipes for solving common problems,
on topics ranging from basic data structures, classes, and objects, to web
development, distributed programming, and multithreading
Revised for Ruby 2.1, each recipe includes a discussion on why and how
the solution works You’ll find recipes suitable for all skill levels, from
Ruby newbies to experts who need an occasional reference With Ruby
Cookbook, you’ll not only save time, but keep your brain percolating with
new ideas as well
Recipes cover:
■ Data structures including strings, numbers, date and time,
arrays, hashes, files, and directories
■ Using Ruby’s code blocks, also known as closures
■ OOP features such as classes, methods, objects, and modules
■ XML and HTML, databases and persistence, and graphics and
other formats
■ Web development with Rails and Sinatra
■ Internet services, web services, and distributed programming
■ Software testing, debugging, packaging, and distributing
■ Multitasking, multithreading, and extending Ruby with other
languages
Lucas Carlson founded AppFog, a PaaS that leverages the open source Cloud
Foundry project A professional developer for 20 years, he specializes in Ruby on
Rails development Lucas has written Programming for PaaS and Ruby Cookbook,
First Edition (both O’Reilly) He maintains a website at http://www.lucascarlson.net/.
Leonard Richardson has been programming since he was eight years old
Recently, the quality of his code has improved somewhat He is responsible for
programming language libraries, including Rubyful Soup He maintains a website
Upd ate
d f
or R uby 2 1
Trang 3Lucas Carlson and Leonard Richardson
Ruby Cookbook
SECOND EDITION
Trang 4[M]
Ruby Cookbook
by Lucas Carlson and Leonard Richardson
Copyright © 2015 Lucas Carlson and Leonard Richardson All rights reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use Online editions are also available for most titles (http://safaribooksonline.com) For more information, contact our corporate/
institutional sales department: 800-998-9938 or corporate@oreilly.com.
Editors: Brian Anderson and Allyson MacDonald
Production Editor: Matthew Hacker
Proofreader: Rachel Monaghan
Indexer: Angela Howard
Interior Designer: David Futato Cover Designer: Ellie Volckhausen Illustrator: Rebecca Demarest
July 2006: First Edition
March 2015: Second Edition
Revision History for the Second Edition
2015-03-10: First Release
See http://oreilly.com/catalog/errata.csp?isbn=9781449373719 for release details.
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc Ruby Cookbook, the cover image of a
side-striped jackal, and related trade dress are trademarks of O’Reilly Media, Inc.
While the publisher and the authors have used good faith efforts to ensure that the information and instructions contained in this work are accurate, the publisher and the authors disclaim all responsibility for errors or omissions, including without limitation responsibility for damages resulting from the use of
or reliance on this work Use of the information and instructions contained in this work is at your own risk If any code samples or other technology this work contains or describes is subject to open source licenses or the intellectual property rights of others, it is your responsibility to ensure that your use thereof complies with such licenses and/or rights.
Trang 5For Yoscelina, my muse and inspiration for everything great I have ever accomplished.
For Hugh and Valentina, the most incredible miracles ever.
For Tess, who sat by me the whole time.
—Lucas Carlson
For Sumana.
—Leonard Richardson
Trang 7Table of Contents
Preface xvii
1 Ruby 2.1 1
1.1 What’s Different Between Ruby 1.8 and 2.1? 2
1.2 YARV (Yet Another Ruby VM) Bytecode Interpreter 9
1.3 Syntax Changes 11
1.4 Keyword Arguments 14
1.5 Performance Enhancements 15
1.6 Refinements 16
1.7 Debugging with DTrace and TracePoint 17
1.8 Module Prepending 19
1.9 New Methods 21
1.10 New Classes 23
1.11 New Standard Libraries 26
1.12 What’s Next? 27
2 Strings 29
2.1 Building a String from Parts 33
2.2 Substituting Variables into Strings 35
2.3 Substituting Variables into an Existing String 37
2.4 Reversing a String by Words or Characters 39
2.5 Representing Unprintable Characters 40
2.6 Converting Between Characters and Values 43
2.7 Converting Between Strings and Symbols 44
2.8 Processing a String One Character at a Time 45
2.9 Processing a String One Word at a Time 47
2.10 Changing the Case of a String 49
2.11 Managing Whitespace 50
v
Trang 82.12 Testing Whether an Object Is String-Like 52
2.13 Getting the Parts of a String You Want 53
2.14 Word-Wrapping Lines of Text 54
2.15 Generating a Succession of Strings 56
2.16 Matching Strings with Regular Expressions 59
2.17 Replacing Multiple Patterns in a Single Pass 61
2.18 Validating an Email Address 63
2.19 Classifying Text with a Bayesian Analyzer 66
3 Numbers 69
3.1 Parsing a Number from a String 70
3.2 Comparing Floating-Point Numbers 73
3.3 Representing Numbers to Arbitrary Precision 76
3.4 Representing Rational Numbers 79
3.5 Generating Random Numbers 80
3.6 Converting Between Numeric Bases 82
3.7 Taking Logarithms 83
3.8 Finding Mean, Median, and Mode 86
3.9 Converting Between Degrees and Radians 89
3.10 Multiplying Matrices 90
3.11 Solving a System of Linear Equations 94
3.12 Using Complex Numbers 97
3.13 Simulating a Subclass of Fixnum 99
3.14 Doing Math with Roman Numbers 103
3.15 Generating a Sequence of Numbers 109
3.16 Generating Prime Numbers 112
3.17 Checking a Credit Card Checksum 116
4 Date and Time 119
4.1 Finding Today’s Date 122
4.2 Parsing Dates, Precisely or Fuzzily 126
4.3 Printing a Date 129
4.4 Iterating Over Dates 134
4.5 Doing Date Arithmetic 135
4.6 Counting the Days Since an Arbitrary Date 138
4.7 Converting Between Time Zones 140
4.8 Checking Whether Daylight Saving Time Is in Effect 142
4.9 Converting Between Time and DateTime Objects 144
4.10 Finding the Day of the Week 147
4.11 Handling Commercial Dates 149
4.12 Running a Code Block Periodically 150
4.13 Waiting a Certain Amount of Time 152
Trang 94.14 Adding a Timeout to a Long-Running Operation 155
5 Arrays 157
5.1 Iterating Over an Array 159
5.2 Rearranging Values Without Using Temporary Variables 163
5.3 Stripping Duplicate Elements from an Array 165
5.4 Reversing an Array 166
5.5 Sorting an Array 167
5.6 Ignoring Case When Sorting Strings 169
5.7 Making Sure a Sorted Array Stays Sorted 170
5.8 Summing the Items of an Array 175
5.9 Sorting an Array by Frequency of Appearance 177
5.10 Shuffling an Array 179
5.11 Getting the N Smallest Items of an Array 180
5.12 Building a Hash from an Array 183
5.13 Extracting Portions of Arrays 185
5.14 Computing Set Operations on Arrays 188
5.15 Partitioning or Classifying a Set 191
6 Hashes 197
6.1 Using Symbols as Hash Keys 200
6.2 Creating a Hash with a Default Value 201
6.3 Adding Elements to a Hash 203
6.4 Removing Elements from a Hash 205
6.5 Using an Array or Other Modifiable Object as a Hash Key 206
6.6 Keeping Multiple Values for the Same Hash Key 209
6.7 Iterating Over a Hash 210
6.8 Iterating Over a Hash in Insertion Order 213
6.9 Printing a Hash 214
6.10 Inverting a Hash 216
6.11 Choosing Randomly from a Weighted List 217
6.12 Building a Histogram 220
6.13 Remapping the Keys and Values of a Hash 222
6.14 Extracting Portions of Hashes 223
6.15 Searching a Hash with Regular Expressions 224
7 Files and Directories 227
7.1 Checking to See If a File Exists 230
7.2 Checking Your Access to a File 232
7.3 Changing the Permissions on a File 234
7.4 Seeing When a File Was Last Used 237
7.5 Listing a Directory 239
Table of Contents | vii
Trang 107.6 Reading the Contents of a File 242
7.7 Writing to a File 246
7.8 Writing to a Temporary File 247
7.9 Picking a Random Line from a File 249
7.10 Comparing Two Files 250
7.11 Performing Random Access on “Read-Once” Input Streams 254
7.12 Walking a Directory Tree 256
7.13 Locking a File 259
7.14 Backing Up to Versioned Filenames 262
7.15 Pretending a String Is a File 265
7.16 Redirecting Standard Input or Output 268
7.17 Processing a Binary File 270
7.18 Deleting a File 274
7.19 Truncating a File 275
7.20 Finding the Files You Want 277
7.21 Finding and Changing the Current Working Directory 279
8 Code Blocks and Iteration 281
8.1 Creating and Invoking a Block 284
8.2 Writing a Method That Accepts a Block 286
8.3 Binding a Block Argument to a Variable 289
8.4 Blocks as Closures: Using Outside Variables Within a Code Block 291
8.5 Writing an Iterator Over a Data Structure 293
8.6 Changing the Way an Object Iterates 296
8.7 Writing Block Methods That Classify or Collect 298
8.8 Stopping an Iteration 300
8.9 Looping Through Multiple Iterables in Parallel 302
8.10 Hiding Setup and Cleanup in a Block Method 306
8.11 Coupling Systems Loosely with Callbacks 308
9 Objects and Classes 313
9.1 Managing Instance Data 316
9.2 Managing Class Data 318
9.3 Checking Class or Module Membership 321
9.4 Writing an Inherited Class 323
9.5 Overloading Methods 326
9.6 Validating and Modifying Attribute Values 328
9.7 Defining a Virtual Attribute 330
9.8 Delegating Method Calls to Another Object 331
9.9 Converting and Coercing Objects to Different Types 334
9.10 Getting a Human-Readable Printout of Any Object 339
9.11 Accepting or Passing a Variable Number of Arguments 341
Trang 119.12 Using Keyword Arguments 343
9.13 Calling a Superclass’s Method 345
9.14 Creating an Abstract Method 347
9.15 Freezing an Object to Prevent Changes 350
9.16 Making a Copy of an Object 353
9.17 Declaring Constants 356
9.18 Implementing Class and Singleton Methods 358
9.19 Controlling Access by Making Methods Private 360
10 Modules and Namespaces 365
10.1 Simulating Multiple Inheritance with Mixins 366
10.2 Extending Specific Objects with Modules 370
10.3 Mixing in Class Methods 372
10.4 Implementing Enumerable: Write One Method, Get 48 Free 373
10.5 Avoiding Naming Collisions with Namespaces 377
10.6 Automatically Loading Libraries as Needed 378
10.7 Including Namespaces 380
10.8 Initializing Instance Variables Defined by a Module 382
10.9 Automatically Initializing Mixed-in Modules 383
10.10 Prepending Modules 386
11 Reflection and Metaprogramming 389
11.1 Finding an Object’s Class and Superclass 390
11.2 Listing an Object’s Methods 391
11.3 Listing Methods Unique to an Object 394
11.4 Getting a Reference to a Method 396
11.5 Fixing Bugs in Someone Else’s Class 398
11.6 Listening for Changes to a Class 400
11.7 Checking Whether an Object Has Necessary Attributes 403
11.8 Responding to Calls to Undefined Methods 404
11.9 Automatically Initializing Instance Variables 409
11.10 Avoiding Boilerplate Code with Metaprogramming 410
11.11 Metaprogramming with String Evaluations 413
11.12 Evaluating Code in an Earlier Context 415
11.13 Undefining a Method 417
11.14 Aliasing Methods 420
11.15 Doing Aspect-Oriented Programming 423
11.16 Enforcing Software Contracts 425
12 XML and HTML 431
12.1 Checking That XML Is Well Formed 432
12.2 Extracting Data from a Document’s Tree Structure 434
Table of Contents | ix
Trang 1212.3 Extracting Data While Parsing a Document 436
12.4 Navigating a Document with XPath 438
12.5 Converting an XML Document into a Hash 441
12.6 Validating an XML Document 444
12.7 Substituting XML Entities 445
12.8 Creating and Modifying XML Documents 448
12.9 Compressing Whitespace in an XML Document 452
12.10 Guessing a Document’s Encoding 453
12.11 Converting from One Encoding to Another 454
12.12 Extracting All the URLs from an HTML Document 456
12.13 Transforming Plain Text to HTML 459
12.14 Converting HTML Documents from the Web into Text 460
12.15 Creating a Simple Feed Aggregator 463
13 Graphics and Other File Formats 469
13.1 Thumbnailing Images 470
13.2 Adding Text to an Image 473
13.3 Converting One Image Format to Another 476
13.4 Graphing Data 479
13.5 Adding Graphical Context with Sparklines 482
13.6 Symmetrically Encrypting Data 485
13.7 Parsing Comma-Separated Data 487
13.8 Parsing Not-Quite-Comma-Separated Data 489
13.9 Generating and Parsing Excel Spreadsheets 490
13.10 Compressing and Archiving Files with Gzip and Tar 492
13.11 Reading and Writing ZIP Files 495
13.12 Reading and Writing Configuration Files 497
13.13 Generating PDF Files 499
13.14 Representing Data as MIDI Music 503
14 Databases and Persistence 507
14.1 Serializing Data with YAML 511
14.2 Serializing Data with Marshal 514
14.3 Persisting Objects with Madeleine 515
14.4 Indexing Unstructured Text with SimpleSearch 518
14.5 Indexing Structured Text with Ferret 520
14.6 Using Berkeley DB Databases 524
14.7 Controlling MySQL on Unix 525
14.8 Finding the Number of Rows Returned by a Query 526
14.9 Talking Directly to a MySQL Database 528
14.10 Talking Directly to a PostgreSQL Database 531
14.11 Using Object Relational Mapping with ActiveRecord 534
Trang 1314.12 Building Queries Programmatically 538
14.13 Validating Data with ActiveRecord 542
14.14 Preventing SQL Injection Attacks 544
14.15 Using Transactions in ActiveRecord 547
14.16 Adding Hooks to Table Events 549
14.17 Adding Taggability with a Database Mixin 551
15 Internet Services 555
15.1 Grabbing the Contents of a Web Page 556
15.2 Making an HTTPS Web Request 559
15.3 Customizing HTTP Request Headers 561
15.4 Performing DNS Queries 563
15.5 Sending Mail 565
15.6 Reading Mail with IMAP 569
15.7 Reading Mail with POP3 574
15.8 Being an FTP Client 577
15.9 Being a Telnet Client 579
15.10 Being an SSH Client 583
15.11 Copying a File to Another Machine 585
15.12 Being a BitTorrent Client 587
15.13 Pinging a Machine 588
15.14 Writing an Internet Server 589
15.15 Parsing URLs 592
15.16 Writing a CGI Script 595
15.17 Setting Cookies and Other HTTP Response Headers 598
15.18 Handling File Uploads via CGI 600
15.19 Running Servlets with WEBrick 603
15.20 Creating a Real-World HTTP Client 609
16 Web Development: Ruby on Rails 613
16.1 Writing a Simple Rails Application to Show System Status 616
16.2 Passing Data from the Controller to the View 619
16.3 Creating a Layout for Your Header and Footer 621
16.4 Redirecting to a Different Location 624
16.5 Displaying Templates with Render 626
16.6 Integrating a Database with Your Rails Application 629
16.7 Understanding Pluralization Rules 633
16.8 Creating a Login System 636
16.9 Storing Hashed User Passwords in the Database 640
16.10 Escaping HTML and JavaScript for Display 642
16.11 Setting and Retrieving Session Information 643
16.12 Setting and Retrieving Cookies 645
Table of Contents | xi
Trang 1416.13 Extracting Code into Helper Functions 647
16.14 Refactoring the View into Partial Snippets of Views 649
16.15 Adding Dynamic Effects with script.aculo.us 653
16.16 Generating Forms for Manipulating Model Objects 655
16.17 Creating an Ajax Form 660
16.18 Exposing Web Services on Your Website 664
16.19 Sending Mail with Rails 666
16.20 Automatically Sending Error Messages to Your Email 669
16.21 Documenting Your Website 671
16.22 Unit-Testing Your Website 672
16.23 Using breakpoint in Your Web Application 676
17 Web Development: Sinatra 679
17.1 Developing a Minimalistic Web-Services–Based Application 680
17.2 Writing a Simple Sinatra Application to Show System Status 681
17.3 Creating a Layout for Your Header and Footer 682
17.4 Passing Data from the Controller to the View 683
17.5 Redirecting to a Different Location 685
17.6 Integrating a Database with Your Sinatra Application 686
17.7 Setting Status Codes and Headers 688
17.8 Setting and Retrieving Session Information 688
17.9 Setting and Retrieving Cookies 690
17.10 Sending Mail with Sinatra 691
17.11 Building RESTful Web Services on Your Website 692
17.12 Creating RESTful JavaScript Clients for Your Web Services 695
18 Web Services and Distributed Programming 697
18.1 Searching for Books on Amazon 699
18.2 Finding Photos on Flickr 702
18.3 Writing an XML-RPC Client 705
18.4 Writing a SOAP Client 707
18.5 Writing a SOAP Server 709
18.6 Charging a Credit Card 710
18.7 Finding the Cost to Ship Packages via UPS or FedEx 712
18.8 Sharing a Hash Between Any Number of Computers 713
18.9 Implementing a Distributed Queue 717
18.10 Creating a Shared “Whiteboard” 719
18.11 Securing DRb Services with Access Control Lists 722
18.12 Automatically Discovering DRb Services with Rinda 724
18.13 Proxying Objects That Can’t Be Distributed 726
18.14 Storing Data on Distributed RAM with MemCached 729
18.15 Caching Expensive Results with MemCached 731
Trang 1518.16 A Remote-Controlled Jukebox 734
19 Testing, Debugging, Optimizing, and Documenting 741
19.1 Running Code Only in Debug Mode 742
19.2 Raising an Exception 744
19.3 Handling an Exception 746
19.4 Retrying After an Exception 748
19.5 Adding Logging to Your Application 750
19.6 Creating and Understanding Tracebacks 752
19.7 Writing Unit Tests 755
19.8 Running Unit Tests 758
19.9 Testing Code That Uses External Resources 761
19.10 Using debug to Inspect and Change the State of Your Application 765
19.11 Documenting Your Application 768
19.12 Profiling Your Application 772
19.13 Benchmarking Competing Solutions 775
19.14 Running Multiple Analysis Tools at Once 777
20 Packaging and Distributing Software 781
20.1 Finding Libraries by Querying Gem Respositories 782
20.2 Installing and Using a Gem 785
20.3 Requiring a Specific Version of a Gem 787
20.4 Uninstalling a Gem 790
20.5 Reading Documentation for Installed Gems 791
20.6 Packaging Your Code as a Gem 792
20.7 Distributing Your Gems 795
20.8 Installing and Creating Standalone Packages with setup.rb 796
21 Automating Tasks with Rake 801
21.1 Automatically Running Unit Tests 803
21.2 Automatically Generating Documentation 805
21.3 Cleaning Up Generated Files 808
21.4 Automatically Building a Gem 809
21.5 Gathering Statistics About Your Code 811
21.6 Publishing Your Documentation 814
21.7 Running Multiple Tasks in Parallel 816
21.8 Creating a Generic Project Rakefile 817
22 Multitasking and Multithreading 825
22.1 Running a Daemon Process on Unix 826
22.2 Creating a Windows Service 829
22.3 Doing Two Things at Once with Threads 833
Table of Contents | xiii
Trang 1622.4 Synchronizing Access to an Object 835
22.5 Terminating a Thread 838
22.6 Running a Code Block on Many Objects Simultaneously 840
22.7 Limiting Multithreading with a Thread Pool 843
22.8 Driving an External Process with popen 846
22.9 Capturing the Output and Error Streams from a Unix Shell Command 848
22.10 Controlling a Process on Another Machine 849
22.11 Avoiding Deadlock 851
23 User Interface 855
23.1 Resources 856
23.2 Getting Input One Line at a Time 857
23.3 Getting Input One Character at a Time 859
23.4 Parsing Command-Line Arguments 861
23.5 Testing Whether a Program Is Running Interactively 864
23.6 Setting Up and Tearing Down a Curses Program 865
23.7 Clearing the Screen 866
23.8 Determining Terminal Size 868
23.9 Changing Text Color 870
23.10 Reading a Password 871
23.11 Allowing Input Editing with Readline 872
23.12 Making Your Keyboard Lights Blink 874
23.13 Creating a GUI Application with Tk 876
23.14 Creating a GUI Application with wxRuby 880
23.15 Creating a GUI Application with Ruby/GTK 884
23.16 Using AppleScript to Get User Input 888
24 Extending Ruby with Other Languages 891
24.1 Writing a C Extension for Ruby 892
24.2 Using a C Library from Ruby 896
24.3 Calling a C Library Through SWIG 899
24.4 Writing Inline C in Your Ruby Code 902
24.5 Using Java Libraries with JRuby 904
25 System Administration 909
25.1 Scripting an External Program 910
25.2 Managing Windows Services 912
25.3 Running Code as Another User 913
25.4 Running Periodic Tasks Without cron or at 915
25.5 Deleting Files That Match a Regular Expression 916
25.6 Renaming Files in Bulk 919
25.7 Finding Duplicate Files 922
Trang 1725.8 Automating Backups 925
25.9 Normalizing Ownership and Permissions in User Directories 926
25.10 Killing All Processes for a Given User 930
25.11 Using Puppet for DevOps System Administration 932
Index 935
Table of Contents | xv
Trang 19The Ruby programming language is itself a wonderful time-saving tool It makes youmore productive than other programming languages because you spend more timemaking the computer do what you want, and less wrestling with the language Butthere are many ways for a Ruby programmer to spend time without accomplishinganything, and we’ve encountered them all:
• Time spent writing Ruby implementations of common algorithms
• Time spent debugging Ruby implementations of common algorithms.
• Time spent discovering and working around Ruby-specific pitfalls
• Time spent on repetitive tasks (including repetitive programming tasks!) thatcould be automated
• Time spent duplicating work that someone else has already made publiclyavailable
• Time spent searching for a library that does x.
• Time spent evaluating and deciding between the many libraries that do x.
• Time spent learning how to use a library because of poor or outdateddocumentation
xvii
Trang 20• Time lost staying away from a useful technology because it seems intimidating.
We, and the many contributors to this book, recall vividly our own wasted hours anddays We’ve distilled our experiences into this book so that you don’t waste your time
—or at least so you waste it enjoyably on more interesting problems.
Our other goal is to expand your interests If you come to this book wanting to gener‐ate algorithmic music with Ruby then, yes, Recipe 13.14 will save you time over start‐ing from scratch It’s more likely that you’d never considered the possibility until now.Every recipe in this book was developed and written with these two goals in mind: tosave you time, and to keep your brain active with new ideas
Audience
This cookbook is aimed at people who know at least a little bit of Ruby, or who know
a fair amount about programming in general This isn’t a Ruby tutorial (see “OtherResources” on page xxv below for some real tutorials), but if you’re already familiarwith a few other programming languages, you should be able to pick up Ruby byreading through the first 10 chapters of this book and typing in the code listings asyou go
We’ve included recipes suitable for all skill levels, from those who are just starting outwith Ruby, to experts who need an occasional reference We focus mainly on genericprogramming techniques, but we also cover specific application frameworks (likeRuby on Rails and GUI libraries) and best practices (like unit testing)
Even if you just plan to use this book as a reference, we recommend that you skimthrough it once to get a picture of the problems we solve This is a big book, but itdoesn’t solve every problem If you pick it up and you can’t find a solution to your
problem, or one that nudges you in the right direction, then you’ve lost time.
If you skim through this book once beforehand, you’ll get a fair idea of the problems
we cover in this book, and you’ll get a better hit rate You’ll know when this book canhelp you, and when you should consult other books, do a web search, ask a friend, orget help some other way
The Structure of This Book
Each of this book’s chapters focuses on a kind of programming or a particular datatype This overview of the chapters should give you a picture of how we divided upthe recipes Each chapter also has its own, somewhat lengthier introduction, whichgives a more detailed view of its recipes At the very least, we recommend you skimthe chapter introductions and the table of contents
Trang 21A brand new chapter covers what has changed since Ruby 1.8 when the first version
of this book was released:
• Chapter 1, Ruby 2.1, covers what is new in Ruby 2.1
The next six chapters cover Ruby’s built-in data structures:
• Chapter 2, Strings, contains recipes for building, processing, and manipulatingstrings of text We devote a few recipes specifically to regular expressions (Recipe2.16 through Recipe 2.18), but our focus is on Ruby-specific issues, and regularexpressions are a very general tool If you haven’t encountered them yet, or justfind them intimidating, we recommend you go through an online tutorial or
Mastering Regular Expressions by Jeffrey Friedl (O’Reilly)
• Chapter 3, Numbers, covers the representation of different types of numbers: realnumbers, complex numbers, arbitrary-precision decimals, and so on It alsoincludes Ruby implementations of common mathematical and statistical algo‐rithms, and explains some Ruby quirks you’ll run into if you create your ownnumeric types (Recipe 3.13 and Recipe 3.14)
• Chapter 4, Date and Time, covers Ruby’s two interfaces for dealing with time: theone based on the C time library, which may be familiar to you from other pro‐gramming languages, and the one implemented in pure Ruby, which is moreidiomatic
• Chapter 5, Arrays, introduces the array, Ruby’s simplest compound data type.Many of an array’s methods are actually methods of the Enumerable mixin; thismeans you can apply many of these recipes to hashes and other data types Somefeatures of Enumerable are covered in this chapter (Recipe 5.4 and Recipe 5.6),and some are covered in Chapter 8
• Chapter 6, Hashes, covers the hash, Ruby’s other basic compound data type.Hashes make it easy to associate objects with names and find them later (hashes
are sometimes called lookup tables or dictionaries, two telling names) It’s easy to
use hashes along with arrays to build deep and complex data structures
• Chapter 7, Files and Directories, covers techniques for reading, writing, andmanipulating files Ruby’s file access interface is based on the standard C filelibraries, so it may look familiar to you This chapter also covers Ruby’s standardlibraries for searching and manipulating the filesystem; many of these recipesshow up again in Chapter 25
The first six chapters deal with specific algorithmic problems The next four are moreabstract: they’re about Ruby idiom and philosophy If you can’t get the Ruby languageitself to do what you want, or you’re having trouble writing Ruby code that looks theway Ruby “should” look, the recipes in these chapters may help:
Preface | xix
Trang 22• Chapter 8, Code Blocks and Iteration, contains recipes that explore the possibili‐
ties of Ruby’s code blocks (also known as closures).
• Chapter 9, Objects and Classes, covers Ruby’s take on object-oriented program‐ming It contains recipes for writing different types of classes and methods, and afew recipes that demonstrate capabilities of all Ruby objects (such as freezing andcloning)
• Chapter 10, Modules and Namespaces, covers Ruby’s modules These constructsare used to “mix” new behavior into existing classes and to segregate functional‐ity into different namespaces
• Chapter 11, Reflection and Metaprogramming, covers techniques for programati‐cally exploring and modifying Ruby class definitions
Chapter 7 covers basic file access, but doesn’t touch much on specific file formats Wedevote three chapters to popular ways of storing data:
• Chapter 12, XML and HTML, shows how to handle the most popular data inter‐change formats The chapter deals mostly with parsing other people’s XML docu‐ments and web pages (but see Recipe 12.8)
• Chapter 13, Graphics and Other File Formats, covers data interchange formatsother than XML and HTML, with a special focus on generating and manipulat‐ing graphics
• Chapter 14, Databases and Persistence, covers the best Ruby interfaces to datastorage formats, whether you’re serializing Ruby objects to disk, or storing struc‐tured data in a database This chapter demonstrates everything from differentways of serializing data and indexing text, to the Ruby client libraries for popularSQL databases, to full-blown abstraction layers like ActiveRecord that save youfrom having to write SQL at all
Currently the most popular use of Ruby is in network applications (mostly throughRuby on Rails) We devote three chapters to different types of applications:
• Chapter 15, Internet Services, kicks off our networking coverage by illustrating awide variety of clients and servers written with Ruby libraries
• Chapter 16, Web Development: Ruby on Rails, covers the web application frame‐work that’s been driving so much of Ruby’s recent popularity
• Chapter 17, Web Development: Sinatra, covers a popular micro-web framework
• Chapter 18, Web Services and Distributed Programming, covers two techniquesfor sharing information between computers during a Ruby program In order touse a web service, you make an HTTP request of a program on some other com‐puter, usually one you don’t control Ruby’s DRb library lets you share Ruby data
Trang 23structures between programs running on a set of computers, all of which youcontrol.
We then have three chapters on the auxilliary tasks that surround the main program‐ming work of a project:
• Chapter 19, Testing, Debugging, Optimizing, and Documenting, focuses mainly onhandling exception conditions and creating unit tests for your code There arealso several recipes on the processes of debugging and optimization
• Chapter 20, Packaging and Distributing Software, mainly deals with Ruby’s Gempackaging system and the RubyForge server that hosts many gem files Many rec‐ipes in other chapters require that you install a particular gem, so if you’re notfamiliar with gems, we recommend you read Recipe 20.2 in particular The chap‐ter also shows you how to create and distribute gems for your own projects
• Chapter 21, Automating Tasks with Rake, covers the most popular Ruby buildtool With Rake, you can script common tasks like running unit tests or packag‐ing your code as a gem Though it’s usually used in Ruby projects, Rake is ageneral-purpose build language that you can use wherever you might use Make
We close the book with four chapters on miscellaneous topics:
• Chapter 22, Multitasking and Multithreading, shows how to use threads to domore than one thing at once, and how to use Unix subprocesses to run externalcommands
• Chapter 23, User Interface, covers user interfaces (apart from the web interface,which was covered in Chapter 16) We discuss the command-line interface,character-based GUIs with Curses and HighLine, GUI toolkits for various plat‐forms, and more obscure kinds of user interface (Recipe 23.11)
• Chapter 24, Extending Ruby with Other Languages, focuses on hooking up Ruby
to other languages, either for performance or to get access to more libraries Most
of the chapter focuses on getting access to C libraries, but there is one recipeabout JRuby, the Ruby implementation that runs on the Java Virtual Machine(Recipe 24.5)
• Chapter 25, System Administration is full of self-contained programs for doingadministrative tasks, usually using techniques from other chapters The recipeshave a heavy focus on Unix administration, but there are some resources forWindows users (including Recipe 25.2), and some cross-platform scripts
Preface | xxi
Trang 24How the Code Listings Work
Learning from a cookbook means performing the recipes Some of our recipes definebig chunks of Ruby code that you can simply plop into your program and use withoutreally understanding them (Recipe 21.8 is a good example) But most of the recipesdemonstrate techniques, and the best way to learn a technique is to practice it
We wrote the recipes, and their code listings, with this in mind Most of our listingsact like unit tests for the concepts described in the recipe: they poke at objects andshow you the results
Now, a Ruby installation comes with an interactive interpreter called irb Within an
irb session, you can type in lines of Ruby code and see the output immediately Youdon’t have to create a Ruby program file and run it through the interpreter
Most of our recipes are presented in a form that you can type or copy/paste directlyinto an irb session To study a recipe in depth, we recommend that you start an irb
session and run through the code listings as you read it You’ll have a deeper under‐standing of the concept if you do it yourself than if you just read about it Once you’redone, you can experiment further with the objects you defined while running thecode listings
Sometimes we want to draw your attention to the expected result of a Ruby expres‐sion We do this with a Ruby comment containing an ASCII arrow that points to theexpected value of the expression This is the same arrow irb uses to tell you the value
of every expression you type
We also use textual comments to explain some pieces of code Here’s a fragment ofRuby code that we’ve formatted with comments as we would in a recipe:
1 + 2 # => 3
# On a long line, the expected value goes on a new line:
# => 7.41619848709566
To display the expected output of a Ruby expression, we use a comment that has no
ASCII arrow, and that always goes on a new line:
puts "This string is self-referential."
# This string is self-referential.
If you type these two snippets of code into irb, ignoring the comments, you cancheck back against the text and verify that you got the same results we did:
Trang 251 When a program’s behavior depends on the current time, the random number generator, or the presence of certain files on disk, you might not get the exact same results we did, but they should be similar.
irb(main):003:0> puts "This string is self-referential."
This string is self-referential.
irb(main):007:0* puts "This string is self-referential."
This string is self-referential.
=> nil
irb(main):008:0> # This string is self-referential.
We don’t cut corners Most of our recipes demonstrate a complete irb session fromstart to finish, and they include any imports or initialization necessary to illustrate thepoint we’re trying to make If you run the code exactly as it is in the recipe, youshould get the same results we did.1 This fits in with our philosophy that code sam‐ples should be unit tests for the underlying concepts In fact, we tested our code sam‐ples like unit tests, with a Ruby script that parses recipe texts and runs the code list‐ings
The irb session technique doesn’t always work Rails recipes have to run within Rails.Curses recipes take over the screen and don’t play well with irb So sometimes weshow you standalone files We present them in the following format:
#!/usr/bin/ruby -w
# sample_ruby_file.rb: A sample file
1 + 2
puts "This string is self-referential."
Whenever possible, we’ll also show what you’ll get when you run this program; forexample, we might show a screenshot of a GUI program, or a record of the program’soutput when run from the Unix command line:
Preface | xxiii
Trang 26$ ruby sample_ruby_file.rb
This string is self-referential.
Note that the output of sample_ruby_file.rb looks different from the same codeentered into irb Here, there’s no trace of the addition and the square root operations,because they produce no output
Installing the Software
Ruby comes preinstalled on Mac OS X and most Linux installations Windowsdoesn’t come with Ruby, but it’s easy to get it with the One-Click Installer
If you’re on a Unix/Linux system and you don’t have Ruby installed (or you want toupgrade), your distribution’s package system may make a Ruby package available OnDebian GNU/Linux, it’s available as the package ruby-[version]: for instance,
ruby-1.8 or ruby-1.9 Red Hat Linux calls it ruby; so does the DarwinParts system
on Mac OS X
If all else fails, download the Ruby source code and compile it yourself You can getthe Ruby source code through FTP or HTTP by visiting http://www.ruby-lang.org/.Many of the recipes in this book require that you install third-party libraries in theform of Ruby gems In general, we prefer standalone solutions (using only the Rubystandard library) to solutions that use gems, and gem-based solutions to ones thatrequire other kinds of third-party software
If you’re not familiar with gems, consult Chapter 20 as needed With RubyGems built
in, it’s easy to install many other pieces of Ruby code When a recipe says somethinglike “Ruby on Rails is available as the rails gem,” you can issue the following com‐mand from the command line (again, as the superuser):
$ gem install rails
The RubyGems library will download the rails gem (and any other gems on which itdepends) and automatically install them You should then be able to run the code inthe recipe, exactly as it appears
The three most useful gems for new Ruby installations are rails (if you intend tocreate Rails applications) and the two gems provided by the Ruby Facets project: facets_core and facets_more The Facets Core library extends the classes of the Rubystandard library with generally useful methods The Facets More library adds entirelynew classes and modules The Ruby Facets home page has a complete reference.Some Ruby libraries (especially older ones) are not packaged as gems In most casesyou can download a tarball or ZIP file from the RAA, and install it with the techniquedescribed in Recipe 20.8
Trang 27Platform Differences, Version Differences, and Other
Headaches
Except where noted, the recipes describe cross-platform concepts, and the code itselfshould run the same way on Windows, Linux, and Mac OS X Most of the platformdifferences and platform-specific recipes show up in the final chapters: Chapters 22,
23, and 25 (but see the introduction to Chapter 7 for a note about Windowsfilenames)
We wrote and tested the recipes using Ruby version 1.8.4 and Rails version 1.1.2, thelatest stable versions as of the time of writing In a couple of places we mention codechanges you should make if you’re running Ruby 1.9 (the latest unstable version as ofthe time of writing) or 2.0
Despite our best efforts, this book may contain unflagged platform-specific code, not
to mention plain old bugs We apologize for these in advance of their discovery Ifyou have problems with a recipe, check out the errata for this book (see the section
“Comments and Questions” on page xxvii below)
In several recipes in this book, we modify standard Ruby classes like Array to addnew methods (see, for instance, Recipe 2.10, which defines a new method called
String#capitalize_first_letter) These methods are then available to everyinstance of that class in your program This is a fairly common technique in Ruby:both Rails and the aforementioned Facets Core library do it It’s somewhat controver‐sial, though, and it can cause problems (see Recipe 9.4 for an in-depth discussion), so
we felt we should mention it here in the Preface, even though it might be too techni‐cal for people who are new to Ruby
If you don’t want to modify the standard classes, you can put the methods we demon‐strate into a subclass, or define them in the Kernel namespace: that is, define capitalize_first_letter_of_string instead of reopening String and defining capitalize_first_letter inside it
Other Resources
If you need to learn Ruby, the standard reference is Programming Ruby: The Prag‐ matic Programmer’s Guide by Dave Thomas, Chad Fowler, and Andy Hunt (Prag‐
matic Programmers) The first edition is available online in HTML format, but it’s out
of date The second edition is much better and is available as a printed book or asPDF It’s a much better idea to buy the second edition
For Rails, the standard book is Agile Web Development with Rails by Dave Thomas,
David Hansson, Leon Breedt, and Mike Clark (Pragmatic Programmers) There are
Preface | xxv
Trang 28also two books like this one that focus exclusively on Rails: Rails Cookbook by Rob
Orsini (O’Reilly) and Rails Recipes by Chad Fowler (Pragmatic Programmers).
Many people come to Ruby already knowing one or more programming languages.You might find it frustrating to learn Ruby with a big book that thinks it has to teach
you programming and Ruby For such people, we recommend “Ruby User’s Guide”
by Ruby creator Yukihiro Matsumoto It’s a short read, and it focuses on what makesRuby different from other programming languages Its terminology is a little out ofdate, and it presents its code samples through the obsolete eval.rb program (use irb
instead), but it’s the best short introduction we know of
If you are a Java programmer who wants to learn Ruby, check out the blog entry
“Coming to Ruby from Java” by Francis Hwang C++ programmers will also benefitfrom much of what’s in here
Finally, Ruby’s built-in modules, classes, and methods come with excellent documen‐
tation (much of it originally written for Programming Ruby) You can read this docu‐
mentation online at http://www.ruby-doc.org/core/ and http://www.ruby-doc.org/ stdlib/ You can also look it up on your own Ruby installation by using the ri com‐mand Pass in the name of a class or method, and ri will give you the correspondingdocumentation Here are a few examples:
$ ri Array # A class
$ ri Array.new # A class method
$ ri Array#compact # An instance method
Conventions Used in This Book
The following typographical conventions are used in this book:
Constant width bold
Shows commands or other text that should be typed literally by the user
Trang 29Constant width italic
Shows text that should be replaced with user-supplied values
Using Code Examples
This book is here to help you get your job done In general, you may use the code inthis book in your programs and documentation You do not need to contact us forpermission unless you’re reproducing a significant portion of the code For example,writing a program that uses several chunks of code from this book does not require
permission Selling or distributing a CD-ROM of examples from O’Reilly books does
require permission Answering a question by citing this book and quoting examplecode does not require permission Incorporating a significant amount of example
code from this book into your product’s documentation does require permission.
We appreciate, but do not require, attribution An attribution usually includes the
title, author, publisher, and ISBN For example: “Ruby Cookbook, Second Edition, by
Lucas Carlson and Leonard Richardson Copyright 2015 Lucas Carlson and LeonardRichardson, 978-1-449-37371-9.”
If you feel your use of code examples falls outside fair use or the permission givenabove, feel free to contact us at permissions@oreilly.com
Comments and Questions
Please address comments and questions concerning this book to the publisher:O’Reilly Media, Inc
1005 Gravenstein Highway North
Trang 30First we’d like to thank our editor, Michael Loukides, for his help and for acquiescing
to our use of his name in recipe code samples, even when we turned him into a talk‐ing frog The production editor, Colleen Gorman, was also very helpful
This book would have taken longer to write and been less interesting without ourcontributing authors, who, collectively, wrote over 60 of these recipes The roll ofnames includes: Steve Arniel, Ben Bleything, Antonio Cangiano, Mauro Cicio, Maur‐ice Codik, Thomas Enebo, Pat Eyler, Bill Froelich, Rod Gaither, Ben Giddings,Michael Granger, James Edward Gray II, Stefan Lang, Kevin Marshall, MatthewPalmer Chetan Patil, Alun ap Rhisiart, Garrett Rooney, John-Mason Shackelford, PhilTomson, and John Wells They saved us time by lending their knowledge of variousRuby topics, and they enriched the book with their ideas
This book would be of appallingly low quality were it not for our technical reviewers,who spotted dozens of bugs, platform-specific problems, and conceptual errors: John
N Alegre, Dave Burt, Bill Dolinar, Simen Edvardsen, Shane Emmons, Edward Faulk‐ner, Dan Fitzpatrick, Bill Guindon, Stephen Hildrey, Meador Inge, Eric Jacoboni,Julian I Kamil, Randy Kramer, Alex LeDonne, Steven Lumos, Keith Rosenblatt, GeneTani, and R Vrajmohan
Finally, thanks to the programmers and writers of the Ruby community—from thecelebrities like Yukihiro Matsumoto, Dave Thomas, Chad Fowler, and “why” to thehundreds of unsung heroes whose work went into the libraries we demonstratethroughout the book, and whose skill and patience bring more people into the Rubycommunity all the time
Trang 31CHAPTER 1 Ruby 2.1
When the first edition of Ruby Cookbook was published in 2006, Ruby 1.8.4 was the
state of the art and Rails had just reached 1.0 Eight years and more than 100 stablereleases later, the latest version is now Ruby 2.1.1 and Rails has just reached 4.1.0.Over the last eight years, a lot has changed, both big and small:
• A bytecode interpreter replaced the old Ruby MRI
• RubyGems and Rake became part of the standard library
• SOAP and Curses have moved out of the standard library into RubyGems
• New syntax primitives have been added for hashes, procs, and more
• New methods like Object#tap and String#prepend have been added
• New classes like BasicObject, Fiber, and TracePoint have been added
• The MD5 standard library was renamed Digest::MD5
• And much more…
The end result is a cleaner language that runs faster and more efficiently than everbefore For example, a simple Rails application is 167–200% faster in Ruby 2.1than 1.8
For all that has changed, there is thankfully very little that has been broken in terms
of backward compatibility The vast majority of code written for Ruby 1.8 will work
in Ruby 2.1 without any modifications However, and somewhat obviously, if youwrite code for Ruby 2.1, it will likely not work in Ruby 1.8 with some of the syntaxchanges introduced
In between Ruby 1.8 and 2.1 were two other major releases: 1.9 and 2.0 In this chap‐ter, we will group all the changes from versions 1.9 through 2.1 together instead of
1
Trang 32pointing out the specific dot release in which a feature was added or modified Forexample, the YARV bytecode interpreter was added only in Ruby 1.9.4, but we willtalk about it as just one of the many differences between Ruby 1.8 and 2.1.
1.1 What’s Different Between Ruby 1.8 and 2.1?
Problem
You want to know the major differences between Ruby 1.8 and 2.1
Solution
Table 1-1 shows the major changes between Ruby 1.8 and 2.1
Table 1-1 Major changes by type between Ruby 1.8 and 2.1
New syntax → The → operator can replace lambda for brevity New syntax Array You can use %i(foo bar baz) to specify
[:foo, :bar, :baz] for brevity.
New syntax def You can define methods like def foo(x: 1);
puts x; end New class BasicObject New root in class hierarchy.
New syntax Hash You can use {a: 1, b: 2} , which is like {:a =>
1, :b => 2} , for brevity.
New syntax r You can apply the r suffix to numbers to specify rationals
like 1.2r New class GC::Profiler Profiles the garbage collector.
New class Encoding Represents a character encoding.
New class Enumerator::Lazy Delays running enumerations until absolutely necessary New class Fiber Lightweight processes.
New class Random Pseudorandom number generator.
Trang 33Type About Note
New class RubyVM The Ruby interpreter.
New class Socket::Ifaddr Interface address class.
New class TracePoint DTrace-like inspection class.
New method Array.try_convert Tries to convert obj into an array.
New method Array#rotate Creates a new array by rotating the existing array New method Array#keep_if Deletes every element where the block evaluates to false New method Array#sample Chooses a random element.
New method Array#repeated_permutation All repeated permutations.
New method Array#repeated_combination All repeated combinations.
New method Hash#to_h Ubiquitous hash conversion.
New method Hash#default_proc= You can now set the default proc after initialization New method Hash#key An inverted hash lookup.
New method Hash#keep_if Deletes every key-value pair where the block evaluates to
false.
New method Hash#assoc Searches through the hash comparing obj with the key
using == New method Hash#rassoc Searches through the hash comparing obj with the
value using == New method Hash#flatten A one-dimensional flattening of this hash.
New method Hash#compare_by_identity Compares hashes by their identity.
New method Enumerable#to_h Ubiquitous hash conversion.
New method Enumerable#flat_map Creates array with the concatenated results of running
block once for every element in enum New method Enumerable#each_entry Calls block once for each element in self , passing that
element as a parameter, converting multiple values from
yield to an array.
1.1 What’s Different Between Ruby 1.8 and 2.1? | 3
Trang 34Type About Note
New method Enumerable#each_with_object Iterates the given block for each element with an
arbitrary object, and returns the initially given object New method Enumerable#chunk Enumerates over the items, chunking them together
based on the return value of the block.
New method Enumerable#slice_before Creates an enumerator for each chunked element New method Enumerable#lazy Delays running enumerations until absolutely necessary New method Exception#cause Keeps track of the root cause of raised errors New method GC.stat Inspects the garbage collector.
New method Kernel#dir Director name of FILE.
New method Kernel#callee Called name of the current method as a symbol New method Kernel#caller_locations Array of backtrace location objects.
New method Kernel#spawn Similar to Kernel.system but doesn’t wait for the
command to finish New method Kernel#require_relative Tries to load the library named string relative to the
requiring file’s path.
New method Kernel#Hash Ubiquitous hash instantiator.
New method Kernel#Rational Ubiquitous rational instantiator.
New method Kernel#Complex Ubiquitous complex instantiator.
New method Module#class_variable_get Gets class variable.
New method Module#class_variable_set Sets class variable.
New method Module#remove_class_variable Removes class variable.
New method Module#public_constant Makes a list of existing constants public.
New method Module#private_constant Makes a list of existing constants private.
New method Module#singleton_class? Is it a singleton?
Trang 35Type About Note
New method Module#prepend An alternative to Module#include that appends
(overwrites) class methods.
New method Module#public_instance_method Public instance methods.
New method Module#refine Allows you to refine an existing class.
New method Module#using Allows you to apply monkey patches in a scoped way New method IO#wait_writable Waits until a file becomes writable.
New method Object#!~ Returns true if two objects do not match (using the =~
method).
New method Object#singleton_class Returns the singleton class of obj
New method Object#untrust Marks obj as untrusted.
New method Object#untrusted? Returns true if the object is untrusted.
New method Object#trust Removes the untrusted mark from obj
New method Object#remove_instance_vari
able
Removes the named instance variable from obj New method Object#public_send Unlike Object#send , this calls public methods only New method Object#public_method Similar to method, this searches public method only New method Object#singleton_methods Lists one-off methods.
New method Object#define_singleton_method Creates a one-off method.
New method Object#tap Taps into a method chain to perform operations on
intermediate results.
New method Range#bsearch Binary search available in arrays.
New method Range#cover? Is obj between the begin and end of the range? New method Socket.getifaddrs Accesses network interfaces.
New method String#ascii_only? Returns true for a string that has only ASCII characters New method String#clear Makes a string empty.
1.1 What’s Different Between Ruby 1.8 and 2.1? | 5
Trang 36Type About Note
New method String#chr A one-character string at the beginning of the string New method String#encode Encodes a string with an encoding.
New method String#getbyte Returns a byte as an integer.
New method String#setbyte Modifies a byte as integer.
New method String#byteslice A substring of one byte at a position.
New method String#scrub Removes garbage bytes from strings.
New method String#codepoints Integer ordinals of the characters in str
New method String#prepend Prepends a given string.
New method String#ord Returns the integer ordinal of a one-character string New method String#each_codepoint Enumerates the integerized values of the string New method String#encoding An encoding object that represents the encoding of the
string.
New method String#force_encoding Forces an encoding.
New method String#b A copied string whose encoding is ASCII-8BIT New method String#valid_encoding? True for a string that is encoded correctly.
New method String#to_r Returns rational number.
New method String#to_c Returns complex number.
Trang 37Type About Note
library rake No longer an external library.
Trang 38Type About Note
Moved to core complex Now part of core; no need to require.
Moved to core enumerator Now part of core; no need to require.
Moved to core rational Now part of core; no need to require.
Moved to core thread Now part of core; no need to require.
Trang 39Type About Note
Removed library ftools Merged into fileutils
Removed library generator No longer a standard library.
Removed library importenv No longer a standard library.
Removed library mailread No longer a standard library.
Removed library ping No longer a standard library.
Removed library runit No longer a standard library.
Removed library tcltklib No longer a standard library.
Removed library Win32API No longer a standard library.
Removed library xsd No longer a standard library.
1.2 YARV (Yet Another Ruby VM) Bytecode Interpreter
One of the biggest differences between MRI and YARV was the introduction of abytecode interpreter With any programming language, the first step to running your
1.2 YARV (Yet Another Ruby VM) Bytecode Interpreter | 9
Trang 40code is to tokenize and parse its syntax The MRI would mix parsing syntax with exe‐cuting your code, which ended up being prone to memory leaks and slow executiontimes The YARV interpreter separates parsing from the running of your code.The bytecode interpreter takes the syntax tree and passes it to a virtual machine emu‐lator that knows how to translate the bytecode into machine code The emulator istuned and optimized for the underlying hardware and knows how to translateinstructions to PowerPC or x86 instructions The result in more efficient execution,less memory usage, and a faster language.
Discussion
To understand bytecode interpreters better, let’s examine a simple Ruby syntax tree
(also known as S-expressions):
require 'ripper'
Ripper sexp ("1+1")
# => [:program, [[:binary, [:@int, "1", [1, 0]], :+, [:@int, "1", [1, 2]]]]]
If you have any familiarity with Lisp, you may notice some similarities between a syn‐tax tree and any Lisp dialect For example, let’s replace the brackets with parenthesesand see if the code looks any more familiar: