• 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 th
Trang 2Lucas Carlson and Leonard Richardson
SECOND EDITIONRuby Cookbook, 2E
Trang 3Ruby Cookbook, 2E, Second Edition
by Lucas Carlson and Leonard Richardson
Copyright © 2010 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://my.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: FIX ME!
Copyeditor: FIX ME!
Proofreader: FIX ME!
Indexer: FIX ME!
Cover Designer: Karen Montgomery
Interior Designer: David Futato
Illustrator: Rebecca Demarest November 2014: Second Edition
Revision History for the Second Edition:
2014-04-30: First Early Release revision 1
See http://oreilly.com/catalog/errata.csp?isbn=9781449373719 for release details.
Nutshell Handbook, the Nutshell Handbook logo, and the O’Reilly logo are registered trademarks of O’Reilly Media, Inc !!FILL THIS IN!! and related trade dress are trademarks of O’Reilly Media, Inc.
Many of the designations used by manufacturers and sellers to distinguish their products are claimed as trademarks Where those designations appear in this book, and O’Reilly Media, Inc was aware of a trademark claim, the designations have been printed in caps or initial caps.
While every precaution has been taken in the preparation of this book, the publisher and authors assume
no responsibility for errors or omissions, or for damages resulting from the use of the information contained herein.
ISBN: 978-1-449-37371-9
[?]
Trang 4For 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 6Table 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 7
1.3 Syntax Changes 9
1.4 Keyword Arguments 11
1.5 Performance Enhancements 12
1.6 Refinements 14
1.7 Debugging with DTrace and TracePoint 15
1.8 Module Prepending 17
1.9 New Methods 18
1.10 New Classes 21
1.11 New Standard Libraries 23
1.12 What’s Next? 25
2 Strings 27
2.1 Building a String from Parts 31
2.2 Substituting Variables into Strings 32
2.3 Substituting Variables into an Existing String 35
2.4 Reversing a String by Words or Characters 37
2.5 Representing Unprintable Characters 38
2.6 Converting Between Characters and Values 41
2.7 Converting Between Strings and Symbols 42
2.8 Processing a String One Character at a Time 43
2.9 Processing a String One Word at a Time 45
2.10 Changing the Case of a String 46
2.11 Managing Whitespace 48
2.12 Testing Whether an Object Is String-Like 50
v
Trang 72.13 Getting the Parts of a String You Want 51
2.14 Word-Wrapping Lines of Text 52
2.15 Generating a Succession of Strings 54
2.16 Matching Strings with Regular Expressions 57
2.17 Replacing Multiple Patterns in a Single Pass 59
2.18 Validating an Email Address 61
2.19 Classifying Text with a Bayesian Analyzer 64
3 Numbers 67
3.1 Parsing a Number from a String 68
3.2 Comparing Floating-Point Numbers 71
3.3 Representing Numbers to Arbitrary Precision 74
3.4 Representing Rational Numbers 77
3.5 Generating Random Numbers 79
3.6 Converting Between Numeric Bases 80
3.7 Taking Logarithms 82
3.8 Finding Mean, Median, and Mode 84
3.9 Converting Between Degrees and Radians 87
3.10 Multiplying Matrices 88
3.11 Solving a System of Linear Equations 93
3.12 Using Complex Numbers 95
3.13 Simulating a Subclass of Fixnum 98
3.14 Doing Math with Roman Numbers 102
3.15 Generating a Sequence of Numbers 107
3.16 Generating Prime Numbers 110
3.17 Checking a Credit Card Checksum 115
4 Date and Time 117
4.1 Finding Today’s Date 120
4.2 Parsing Dates, Precisely or Fuzzily 124
4.3 Printing a Date 127
4.4 Iterating Over Dates 131
4.5 Doing Date Arithmetic 133
4.6 Counting the Days Since an Arbitrary Date 135
4.7 Converting Between Time Zones 137
4.8 Checking Whether Daylight Saving Time Is in Effect 139
4.9 Converting Between Time and DateTime Objects 141
4.10 Finding the Day of the Week 144
4.11 Handling Commercial Dates 146
4.12 Running a Code Block Periodically 147
4.13 Waiting a Certain Amount of Time 149
Trang 84.14 Adding a Timeout to a Long-Running Operation 152
5 Arrays 155
5.1 Iterating Over an Array 157
5.2 Rearranging Values Without Using Temporary Variables 161
5.3 Stripping Duplicate Elements from an Array 163
5.4 Reversing an Array 164
5.5 Sorting an Array 165
5.6 Ignoring Case When Sorting Strings 167
5.7 Making Sure a Sorted Array Stays Sorted 168
5.8 Summing the Items of an Array 174
5.9 Sorting an Array by Frequency of Appearance 175
5.10 Shuffling an Array 177
5.11 Getting the N Smallest Items of an Array 179
5.12 Building Up a Hash Using Injection 181
5.13 Extracting Portions of Arrays 183
5.14 Computing Set Operations on Arrays 187
5.15 Partitioning or Classifying a Set 189
6 Hashes 195
6.1 Using Symbols as Hash Keys 198
6.2 Creating a Hash with a Default Value 199
6.3 Adding Elements to a Hash 201
6.4 Removing Elements from a Hash 203
6.5 Using an Array or Other Modifiable Object as a Hash Key 205
6.6 Keeping Multiple Values for the Same Hash Key 207
6.7 Iterating Over a Hash 208
6.8 Iterating Over a Hash in Insertion Order 211
6.9 Printing a Hash 212
6.10 Inverting a Hash 214
6.11 Choosing Randomly from a Weighted List 216
6.12 Building a Histogram 218
6.13 Remapping the Keys and Values of a Hash 220
6.14 Extracting Portions of Hashes 221
6.15 Searching a Hash with Regular Expressions 222
7 Files and Directories 225
7.1 Checking to See If a File Exists 228
7.2 Checking Your Access to a File 230
7.3 Changing the Permissions on a File 232
7.4 Seeing When a File Was Last Used Problem 235
7.5 Listing a Directory 237
Table of Contents | vii
Trang 97.6 Reading the Contents of a File 240
7.7 Writing to a File 244
7.8 Writing to a Temporary File 245
7.9 Picking a Random Line from a File 247
7.10 Comparing Two Files 248
7.11 Performing Random Access on “Read-Once” Input Streams 252
7.12 Walking a Directory Tree 254
7.13 Locking a File 257
7.14 Backing Up to Versioned Filenames 260
7.15 Pretending a String Is a File 263
7.16 Redirecting Standard Input or Output 266
7.17 Processing a Binary File 268
7.18 Deleting a File 272
7.19 Truncating a File 273
7.20 Finding the Files You Want 275
7.21 Finding and Changing the Current Working Directory 277
8 Code Blocks and Iteration 279
8.1 Creating and Invoking a Block 282
8.2 Writing a Method That Accepts a Block 284
8.3 Binding a Block Argument to a Variable 287
8.4 Blocks as Closures: Using Outside Variables Within a Code Block 289
8.5 Writing an Iterator Over a Data Structure 291
8.6 Changing the Way an Object Iterates 294
8.7 Writing Block Methods That Classify or Collect 296
8.8 Stopping an Iteration 298
8.9 Looping Through Multiple Iterables in Parallel 300
8.10 Hiding Setup and Cleanup in a Block Method 304
8.11 Coupling Systems Loosely with Callbacks 307
9 Objects and Classes 311
9.1 Managing Instance Data 313
9.2 Managing Class Data 316
9.3 Checking Class or Module Membership 319
9.4 Writing an Inherited Class 321
9.5 Overloading Methods 324
9.6 Validating and Modifying Attribute Values 326
9.7 Defining a Virtual Attribute 328
9.8 Delegating Method Calls to Another Object 329
9.9 Converting and Coercing Objects to Different Types 332
9.10 Getting a Human-Readable Printout of Any Object 337
9.11 Accepting or Passing a Variable Number of Arguments 339
Trang 109.12 Keyword Arguments 341
9.13 Calling a Superclass’s Method 343
9.14 Creating an Abstract Method 346
9.15 Freezing an Object to Prevent Changes 348
9.16 Making a Copy of an Object 351
9.17 Declaring Constants 354
9.18 Implementing Class and Singleton Methods 356
9.19 Controlling Access by Making Methods Private 358
10 Modules and Namespaces 363
10.1 Simulating Multiple Inheritance with Mixins 364
10.2 Extending Specific Objects with Modules 367
10.3 Mixing in Class Methods 369
10.4 Implementing Enumerable: Write One Method, Get 48 Free 371
10.5 Avoiding Naming Collisions with Namespaces 375
10.6 Automatically Loading Libraries as Needed 376
10.7 Including Namespaces 378
10.8 Initializing Instance Variables Defined by a Module 380
10.9 Automatically Initializing Mixed-In Modules 381
10.10 Prepending Modules 384
11 Reflection and Metaprogramming 387
11.1 Finding an Object’s Class and Superclass 388
11.2 Listing an Object’s Methods 389
11.3 Listing Methods Unique to an Object 392
11.4 Getting a Reference to a Method 393
11.5 Fixing Bugs in Someone Else’s Class 396
11.6 Listening for Changes to a Class 397
11.7 Checking Whether an Object Has Necessary Attributes 400
11.8 Responding to Calls to Undefined Methods 402
11.9 Automatically Initializing Instance Variables 406
11.10 Avoiding Boilerplate Code with Metaprogramming 408
11.11 Metaprogramming with String Evaluations 410
11.12 Evaluating Code in an Earlier Context 413
11.13 Undefining a Method 414
11.14 Aliasing Methods 417
11.15 Doing Aspect-Oriented Programming 420
11.16 Enforcing Software Contracts 423
12 XML and HTML 429
12.1 Checking XML Well-Formedness 430
12.2 Extracting Data from a Document’s Tree Structure 432
Table of Contents | ix
Trang 1112.3 Extracting Data While Parsing a Document 434
12.4 Navigating a Document with XPath 436
12.5 Converting an XML Document into a Hash 439
12.6 Validating an XML Document 442
12.7 Substituting XML Entities 444
12.8 Creating and Modifying XML Documents 447
12.9 Compressing Whitespace in an XML Document 450
12.10 Guessing a Document’s Encoding 452
12.11 Converting from One Encoding to Another 453
12.12 Extracting All the URLs from an HTML Document 455
12.13 Transforming Plain Text to HTML 458
12.14 Converting HTML Documents from the Web into Text 459
12.15 A Simple Feed Aggregator 462
13 Graphics and Other File Formats 467
13.1 Thumbnailing Images 467
13.2 Adding Text to an Image 470
13.3 Converting One Image Format to Another 474
13.4 Graphing Data 477
13.5 Adding Graphical Context with Sparklines 481
13.6 Symetrically Encrypting Data 484
13.7 Parsing Comma-Separated Data 485
13.8 Parsing Not-Quite-Comma-Separated Data 488
13.9 Generating and Parsing Excel Spreadsheets 489
13.10 Compressing and Archiving Files with Gzip and Tar 491
13.11 Reading and Writing ZIP Files 494
13.12 Reading and Writing Configuration Files 495
13.13 Generating PDF Files 497
13.14 Representing Data as MIDI Music 502
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 526
14.8 Finding the Number of Rows Returned by a Query 527
14.9 Talking Directly to a MySQL Database 529
14.10 Talking Directly to a PostgreSQL Database 532
14.11 Using Object Relational Mapping with ActiveRecord 534
Trang 1214.12 Using Object Relational Mapping with Og 539
14.13 Building Queries Programmatically 543
14.14 Validating Data with ActiveRecord 546
14.15 Preventing SQL Injection Attacks 549
14.16 Using Transactions in ActiveRecord 552
14.17 Adding Hooks to Table Events 554
14.18 Adding Taggability with a Database Mixin 557
15 Internet Services 561
15.1 Grabbing the Contents of a Web Page 562
15.2 Making an HTTPS Web Request 565
15.3 Customizing HTTP Request Headers 567
15.4 Performing DNS Queries 569
15.5 Sending Mail 571
15.6 Reading Mail with IMAP 575
15.7 Reading Mail with POP3 580
15.8 Being an FTP Client 583
15.9 Being a Telnet Client 585
15.10 Being an SSH Client 589
15.11 Copying a File to Another Machine 591
15.12 Being a BitTorrent Client 593
15.13 Pinging a Machine 594
15.14 Writing an Internet Server 595
15.15 Parsing URLs 597
15.16 Writing a CGI Script 601
15.17 Setting Cookies and Other HTTP Response Headers 604
15.18 Handling File Uploads via CGI 606
15.19 Running Servlets with WEBrick 609
15.20 A Real-World HTTP Client 615
16 Web Development: Ruby on Rails 619
16.1 Writing a Simple Rails Application to Show System Status 622
16.2 Passing Data from the Controller to the View 625
16.3 Creating a Layout for Your Header and Footer 627
16.4 Redirecting to a Different Location 630
16.5 Displaying Templates with Render 632
16.6 Integrating a Database with Your Rails Application 635
16.7 Understanding Pluralization Rules 639
16.8 Creating a Login System 641
16.9 Storing Hashed User Passwords in the Database 645
16.10 Escaping HTML and JavaScript for Display 648
16.11 Setting and Retrieving Session Information 649
Table of Contents | xi
Trang 1316.12 Setting and Retrieving Cookies 651
16.13 Extracting Code into Helper Functions 653
16.14 Refactoring the View into Partial Snippets of Views 655
16.15 Adding Dynamic Effects with script.aculo.us 658
16.16 Generating Forms for Manipulating Model Objects 661
16.17 Creating an Ajax Form 666
16.18 Exposing Web Services on Your Web Site 669
16.19 Sending Mail with Rails 672
16.20 Automatically Sending Error Messages to Your Email 674
16.21 Documenting Your Web Site 676
16.22 Unit Testing Your Web Site 677
16.23 Using breakpoint in Your Web Application 681
17 Web Development: Sinatra 685
17.1 Introduction to Minimalistic Web-Services Based Development 686
17.2 Writing a Simple Sinatra Application to Show System Status 687
17.3 Creating a Layout for Your Header and Footer 688
17.4 Passing Data From the Controller to the View 689
17.5 Redirecting to a Different Location 691
17.6 Integrating a Database with Your Sinatra Application 692
17.7 Setting Status Codes and Headers 694
17.8 Setting and Retrieving Session Information 695
17.9 Setting and Retrieving Cookies 696
17.10 Sending Mail With Sinatra 697
17.11 Building RESTful Web Services on Your Website 698
17.12 Creating RESTful Javascript Clients for Your Web Services 701
18 Web Services and Distributed Programming 703
18.1 Searching for Books on Amazon 705
18.2 Finding Photos on Flickr 708
18.3 Writing an XML-RPC Client 711
18.4 Writing a SOAP Client 713
18.5 Writing a SOAP Server 715
18.6 Charging a Credit Card 717
18.7 Finding the Cost to Ship Packages via UPS or FedEx 718
18.8 Sharing a Hash Between Any Number of Computers 719
18.9 Implementing a Distributed Queue 723
18.10 Creating a Shared “Whiteboard” 726
18.11 Securing DRb Services with Access Control Lists 729
18.12 Automatically Discovering DRb Services with Rinda 730
18.13 Proxying Objects That Can’t Be Distributed 733
18.14 Storing Data on Distributed RAM with MemCached 735
Trang 1418.15 Caching Expensive Results with MemCached 737
18.16 A Remote-Controlled Jukebox 741
19 Testing, Debugging, Optimizing, and Documenting 747
19.1 Running Code Only in Debug Mode 748
19.2 Raising an Exception 750
19.3 Handling an Exception 752
19.4 Retry After an Exception 754
19.5 Adding Logging to Your Application 756
19.6 Creating and Understanding Tracebacks 758
19.7 Writing Unit Tests 761
19.8 Running Unit Tests 764
19.9 Testing Code That Uses External Resources 767
19.10 Using debug to Inspect and Change the State of Your Application 771
19.11 Documenting Your Application 774
19.12 Profiling Your Application 779
19.13 Benchmarking Competing Solutions 782
19.14 Running Multiple Analysis Tools at Once 784
20 Packaging and Distributing Software 787
20.1 Finding Libraries by Querying Gem Respositories 788
20.2 Installing and Using a Gem 791
20.3 Requiring a Specific Version of a Gem 793
20.4 Uninstalling a Gem 796
20.5 Reading Documentation for Installed Gems 797
20.6 Packaging Your Code as a Gem 798
20.7 Distributing Your Gems 801
20.8 Installing and Creating Standalone Packages with setup.rb 802
21 Automating Tasks with Rake 807
21.1 Automatically Running Unit Tests 809
21.2 Automatically Generating Documentation 811
21.3 Cleaning Up Generated Files 814
21.4 Automatically Building a Gem 815
21.5 Gathering Statistics About Your Code 817
21.6 Publishing Your Documentation 820
21.7 Running Multiple Tasks in Parallel 822
21.8 A Generic Project Rakefile 823
22 Multitasking and Multithreading 831
22.1 Running a Daemon Process on Unix 832
22.2 Creating a Windows Service 835
Table of Contents | xiii
Trang 1522.3 Doing Two Things at Once with Threads 839
22.4 Synchronizing Access to an Object 841
22.5 Terminating a Thread 844
22.6 Running a Code Block on Many Objects Simultaneously 846
22.7 Limiting Multithreading with a Thread Pool 849
22.8 Driving an External Process with popen 852
22.9 Capturing the Output and Error Streams from a Unix Shell Command 854
22.10 Controlling a Process on Another Machine 855
22.11 Avoiding Deadlock 857
23 User Interface 861
23.1 Resources 862
23.2 Getting Input One Line at a Time 863
23.3 Getting Input One Character at a Time 865
23.4 Parsing Command-Line Arguments 867
23.5 Testing Whether a Program Is Running Interactively 870
23.6 Setting Up and Tearing Down a Curses Program 871
23.7 Clearing the Screen 872
23.8 Determining Terminal Size 874
23.9 Changing Text Color 876
23.10 Reading a Password 877
23.11 Allowing Input Editing with Readline 878
23.12 Making Your Keyboard Lights Blink 880
23.13 Creating a GUI Application with Tk 882
23.14 Creating a GUI Application with wxRuby 887
23.15 Creating a GUI Application with Ruby/GTK 891
23.16 Using AppleScript to Get User Input 895
24 Extending Ruby with Other Languages 897
24.1 Writing a C Extension for Ruby 898
24.2 Using a C Library from Ruby 902
24.3 Calling a C Library Through SWIG 905
24.4 Writing Inline C in Your Ruby Code 908
24.5 Using Java Libraries with JRuby 910
25 System Administration 915
25.1 Scripting an External Program 916
25.2 Managing Windows Services 917
25.3 Running Code as Another User 919
25.4 Running Periodic Tasks Without cron or at 921
25.5 Deleting Files That Match a Regular Expression 922
25.6 Renaming Files in Bulk 925
Trang 1625.7 Finding Duplicate Files 928
25.8 Automating Backups 931
25.9 Normalizing Ownership and Permissions in User Directories 933
25.10 Killing All Processes for a Given User 936
25.11 DevOps System Administration with Puppet 938
Table of Contents | xv
Trang 18The 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 But thereare many ways for a Ruby programmer to spend time without accomplishing anything,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!) that could
be automated
• Time spent duplicating work that someone else has already made publicly available
• 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 outdated documenta‐tion
xvii
Trang 19• 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 enjoyably waste it on more interesting problems.
Our other goal is to expand your interests If you come to this book wanting to generatealgorithmic music with Ruby then, yes, Recipe 13.14 will save you time over startingfrom scratch It’s more likely that you’d never considered the possibility until now Everyrecipe in this book was developed and written with these two goals in mind: to save youtime, 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 the Resourcessection below for some real tutorials), but if you’re already familiar with a few otherprogramming languages, you should be able to pick up Ruby by reading through thefirst 10 chapters of this book and typing in the code listings as you 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 (like Ruby
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 it doesn’tsolve 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 data type.This overview of the chapters should give you a picture of how we divided up the recipes.Each chapter also has its own, somewhat lengthier introduction, which gives a moredetailed view of its recipes At the very least, we recommend you skim the chapterintroductions and the table of contents
A brand new chapter to this book covers what has changed since Ruby 1.8 when thefirst version of this book was released
Trang 20• Chapter 1, What is new in Ruby 2.1.
The next six chapters covering 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 (Recipes2.27, 2.28 through 2.29), but our focus is on Ruby-specific issues, and regular ex‐pressions are a very general tool If you haven’t encountered them yet, or just find
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 also in‐cludes Ruby implementations of common mathematical and statistical algorithms,and explains some Ruby quirks you’ll run into if you create your own numeric types(Recipes 3.13 and 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 more id‐iomatic
• 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; this meansyou can apply many of these recipes to hashes and other data types Some features
of Enumerable are covered in this chapter (Recipes 5.5 and 5.6), and some are cov‐ered in Chapter 8
• Chapter 6, Hashes, covers the hash, Ruby’s other basic compound data type Hashesmake it easy to associate objects with names and find them later (hashes are some‐times called “lookup tables” or “dictionaries,” two telling names) It’s easy to usehashes along with arrays to build deep and complex data structures
• Chapter 7, Files and Directories, covers techniques for reading, writing, and ma‐nipulating files Ruby’s file access interface is based on the standard C file libraries,
so it may look familiar to you This chapter also covers Ruby’s standard libraries forsearching and manipulating the filesystem; many of these recipes show 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
• Chapter 8, Code Blocks and Iteration, contains recipes that explore the possibilities
of Ruby’s code blocks (also known as closures).
Preface | xix
Trang 21• 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 functionalityinto 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 formats otherthan XML and HTML, with a special focus on generating and manipulating graph‐ics
• Chapter 14, Databases and Persistence, covers the best Ruby interfaces to data stor‐age formats, whether you’re serializing Ruby objects to disk, or storing structureddata in a database This chapter demonstrates everything from different ways ofserializing data and indexing text, to the Ruby client libraries for popular SQL da‐tabases, to full-blown abstraction layers like ActiveRecord that save you from having
• 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 datastructures between programs running on a set of computers, all of which you con‐trol
Trang 22We 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 are alsoseveral 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 recipes
in other chapters require that you install a particular gem, so if you’re not familiarwith gems, we recommend you read Recipe 20.2 in particular The chapter alsoshows you how to create and distribute gems for your own projects
• Chapter 21, Automating Tasks with Rake, covers the most popular Ruby build tool.With Rake, you can script common tasks like running unit tests or packaging yourcode as a gem Though it’s usually used in Ruby projects, it’s a general-purpose buildlanguage 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 do morethan one thing at once, and how to use Unix subprocesses to run external com‐mands
• 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 recipe aboutJRuby, the Ruby implementation that runs on the Java Virtual Machine (Recipe24.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 for Win‐dows users (including Recipe 25.2), and some cross-platform scripts
How 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 without
Preface | xxi
Trang 23really 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 listings actlike unit tests for the concepts described in the recipe: they poke at objects and showyou the results
Now, a Ruby installation comes with an interactive interpreter called irb Within anirb 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 directly into
an irb session To study a recipe in depth, we recommend that you start an irb sessionand run through the code listings as you read it You’ll have a deeper understanding ofthe concept if you do it yourself than if you just read about it Once you’re done, youcan experiment further with the objects you defined while running the code listings.Sometimes we want to draw your attention to the expected result of a Ruby expression
We do this with a Ruby comment containing an ASCII arrow that points to the expectedvalue of the expression This is the same arrow irb uses to tell you the value of everyexpression you type
We also use textual comments to explain some pieces of code Here’s a fragment of Rubycode that I’ve formatted with comments as I would in a recipe:
1 + 2 # => 3
# On a long line, the expected value goes on a new line:
Math.sqrt(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)
# => 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 can checkback against the text and verify that you got the same results we did:
irb(main):003:0> puts "This string is self-referential."
This string is self-referential.
=> nil
If you’re reading this book in electronic form, you can copy and paste the code fragmentsinto irb The Ruby interpreter will ignore the comments, but you can use them to make
Trang 241 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 it should be similar.
sure your answers match ours, without having to look back at the text (But you shouldknow that typing in the code yourself, at least the first time, is better for comprehension.)
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 from start
to finish, and they include any imports or initialization necessary to illustrate the pointwe’re trying to make If you run the code exactly as it is in the recipe, you should get thesame results we did.1 This fits in with our philosophy that code samples should be unittests for the underlying concepts In fact, we tested our code samples like unit tests, with
a Ruby script that parses recipe texts and runs the code listings
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 we showyou standalone files We present them in the following format:
#!/usr/bin/ruby -w
# sample_ruby_file.rb: A sample file
1 + 2
Math.sqrt(1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10)
puts "This string is self-referential."
Whenever possible, we’ll also show what you’ll get when you run this program: maybe
a screenshot of a GUI program, or a record of the program’s output when run from theUnix command line:
$ ruby sample_ruby_file.rb
This string is self-referential.
Note that the output of sample_ruby_file.rb looks different from the same code en‐tered into irb Here, there’s no trace of the addition and the square root operations,because they produce no output
Preface | xxiii
Trang 25Installing the Software
Ruby comes preinstalled on Mac OS X and most Linux installations Windows doesn’tcome with Ruby, but it’s easy to get it with the One-Click Installer: see http://ruby forge.org/projects/rubyinstaller/
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 onMac OS X
If all else fails, download the Ruby source code and compile it yourself You can get theRuby 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 the form
of Ruby gems In general, we prefer standalone solutions (using only the Ruby standardlibrary) to solutions that use gems, and gem-based solutions to ones that require otherkinds of third-party software
If you’re not familiar with gems, consult Chapter 20 as needed To get started, all youneed to know is that you first download the Rubygems library from http://rubyforge.org/ projects/rubygems/ (choose the latest release from that page) Unpack the tarball or ZIPfile, change into the rubygems-[version] directory, and run this command as the su‐peruser:
$ ruby setup.rb
The Rubygems library is included in the Windows One-Click Installer, so you don’t have
to worry about this step on Windows
Once you’ve got the Rubygems library installed, it’s easy to install many other pieces ofRuby code When a recipe says something like “Ruby on Rails is available as the railsgem,” you can issue the following command from the command line (again, as thesuperuser):
$ gem install rails include-dependencies
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 in therecipe, exactly as it appears
The three most useful gems for new Ruby installations are rails (if you intend to createRails 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 homepage (http://facets.rubyforge.org/) has
a complete reference
Trang 26Some Ruby libraries (especially older ones) are not packaged as gems Most of the non‐gem libraries mentioned in this book have entries in the Ruby Application Archive(http://raa.ruby-lang.org/), a directory of Ruby programs and libraries In most casesyou can download a tarball or ZIP file from the RAA, and install it with the techniquedescribed in Recipe 20.8.
Platform 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: Chapter 22,
Chapter 23, and Chapter 25 (but see the introduction to Chapter 7 for a note aboutWindows filenames)
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 If youhave problems with a recipe, check out the eratta for this book (see below)
In several recipes in this book, we modify standard Ruby classes like Array to add newmethods (see, for instance, Recipe 2.20, which defines a new method called String#capitalize_first_letter) These methods are then available to every instance of thatclass in your program This is a fairly common technique in Ruby: both Rails and theFacets Core library mentioned above do it It’s somewhat controversial, though, and itcan cause problems (see Recipe 9.4 for an in-depth discussion), so we felt we shouldmention it here in the Preface, even though it might be too technical for people who arenew 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
Trang 27as a printed book or as PDF (http://www.pragmaticprogrammer.com/titles/ruby/) It’s amuch better idea to buy the second edition and use the first edition as a handy referencethan to try to read the first edition.
“Why’s (Poignant) Guide to Ruby,” by “why the lucky stiff,” teaches Ruby with stories,like an English primer Excellent for creative beginners (http://poignantguide.net/ruby/)
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 also
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).
Some common Ruby pitfalls are explained in the Ruby FAQ (http://www.rubycen tral.com/faq/, starting in Section 4) and in “Things That Newcomers to Ruby ShouldKnow” (http://www.glue.umd.edu/~billtj/ruby.html)
Many people come to Ruby already knowing one or more programming languages Youmight 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 creator Yukihiro Mat‐
sumoto’s “Ruby User’s Guide” (http://www.ruby-doc.org/docs/UsersGuide/rg/) It’s ashort read, and it focuses on what makes Ruby different from other programming lan‐guages Its terminology is a little out of date, and it presents its code samples throughthe obsolete eval.rb program (use irb instead), but it’s the best short introduction weknow of
There are a few articles especially for Java programmers who want to learn Ruby: JimWeirich’s “10 Things Every Java Programmer Should Know About Ruby” (http://ones tepback.org/articles/10things/), Francis Hwang’s blog entry “Coming to Ruby from Java”(http://fhwang.net/blog/40.html), and Chris Williams’s collection of links, “From Java
to Ruby (With Love)” (http://cwilliams.textdriven.com/pages/java_to_ruby) Despite thenames, C++ programmers will also benefit from much of what’s in these pieces.The Ruby Bookshelf (http://books.rubyveil.com/books/Bookshelf/Introduction/Book shelf) has produced a number of free books on Ruby, including many of the ones men‐tioned above, in an easy-to-read HTML format
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 command.Pass in the name of a class or method, and ri will give you the corresponding docu‐mentation Here are a few examples:
$ ri Array # A class
$ ri Array.new # A class method
$ ri Array#compact # An instance method
Trang 28Conventions 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
Constant 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 example codedoes 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, by Lucas Carlson and Leo‐
nard Richardson Copyright 2006 O’Reilly Media, Inc., 0-596-52369-6.”
If you feel your use of code examples falls outside fair use or the permission given above,feel free to contact us at permissions@oreilly.com
Comments and Questions
Please address comments and questions concerning this book to the publisher:
Preface | xxvii
Trang 29O’Reilly Media, Inc 1005 Gravenstein Highway North Sebastopol, CA 95472800-998-9938 (in the United States or Canada) 707-829-0515 (international or local)707-829-0104 (fax)
We have a web page for this book, where we list errata, examples, and any additionalinformation You can access this page at:
First 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 talkingfrog The production editor, Colleen Gorman, was also very helpful
This book would have taken longer to write and been less interesting without our con‐tributing authors, who, collectively, wrote over 60 of these recipes The roll of namesincludes: Steve Arniel, Ben Bleything, Antonio Cangiano, Mauro Cicio, Maurice Codik,Thomas Enebo, Pat Eyler, Bill Froelich, Rod Gaither, Ben Giddings, Michael Granger,James Edward Gray II, Stefan Lang, Kevin Marshall, Matthew Palmer Chetan Patil, Alun
ap Rhisiart, Garrett Rooney, John-Mason Shackelford, Phil Tomson, and John Wells.They saved us time by lending their knowledge of various Ruby topics, and they enrichedthe 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 Faulkner,Dan Fitzpatrick, Bill Guindon, Stephen Hildrey, Meador Inge, Eric Jacoboni, Julian I.Kamil, Randy Kramer, Alex LeDonne, Steven Lumos, Keith Rosenblatt, Gene Tani, and
R Vrajmohan
Finally, to the programmers and writers of the Ruby community; from the celebritieslike Yukihiro Matsumoto, Dave Thomas, Chad Fowler, and “why”, to the hundreds ofunsung heroes whose work went into the libraries we demonstrate throughout the book,and whose skill and patience bring more people into the Ruby community all the time
Trang 30CHAPTER 1 Ruby 2.1
When the first edition of the Ruby Cookbook was published in 2006, Ruby 1.8.4 wasthe 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 Overthe 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 sytax primitives have been added for Hashes, Procs and more
• New methods like Object#tap and String#prepend
• New classes like BasicObject, Fiber and TracePoint
• 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 ever before.For example a simple Rails applicaiton is 167-200% faster in Ruby 2.1 than 1.8.For all that has changed, there is thankfully very little that has been broken in terms ofbackwards compatibility The vast majority of code written for Ruby 1.8 will work inRuby 2.1 without any modifications However, and somewhat obviously, if you writecode for Ruby 2.1, it will likely not work in Ruby 1.8 with some of the syntax changesintroduced
In between Ruby 1.8 and 2.1 were two other major releases: 1.9 and 2.0 In this chapter,
we will group all the changes from versions 1.9 through 2.1 together instead of pointingout the specific dot release in which a feature was added or modified For example, the
1
Trang 31YARV bytecode interpreter was added only in Ruby 1.9.4, however we will talk 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?
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 Hash
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 r You can apply the r suffix to numbers to specify rationals like
1.2r
New Class GC::Profiler Profile the garbage collector
New Class Encoding Represents a character encoding
New Class Enumerator::Lazy Delay running enumerations until absolutely necessary New Class Fiber Lightweight processes
New Class Random Pseudo-random number generator
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 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 Choose a random element
New Method Array#repeated_permutation All repeated permutations
New Method Array#repeated_combination All repeated combinations
Trang 32Type About Note
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 New Method Enumerable#each_with_ob
ject
Iterates the given block for each element with an arbitrary object given, 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 elements
New Method Enumerable#lazy Delay running enumerations until absolutely necessary New Method Exception#cause Keeps track of the root cause of raised errors
New Method GC.stat Inspect 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 Symilar 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 Get class var
New Method Module#class_variable_set Set class var
New Method Module#remove_class_vari
Trang 33Type About Note
New Method Module#private_constant Makes a list of existing constants private
New Method Module#singleton_class? Is it a singleton?
New Method Module#prepend An alternative to Module#include which appends
(overwrites) class methods New Method Module#public_in
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_in
stance_variable
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, searches public method only
New Method Object#singleton_methods List one-off methods
New Method Object#define_single
ton_method
Create a one-off method
New Method Object#tap Tap 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 Access network interfaces
New Method String#ascii_only? Returns true for a string which has only ASCII characters New Method String#clear Makes a string empty
New Method String#chr A one-character string at the beginning of the string New Method String#encode Encode 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 Prepend a given string
New Method String#ord Return the Integer ordinal of a one-character string
Trang 34Type About Note
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 Force an Encoding
New Method String#b A copied string whose encoding is ASCII-8BIT
New Method String#valid_encoding? true for a string which encoded correctly
New Method String#to_r Returns Rational number
New Method String#to_c Returns Complex number
Removed Method Array#nitems Removed
Removed Method Array#indexes Removed in favor of Array#values_at
Removed Method Array#indeces Removed in favor of Array#values_at
Removed Method Hash#indexes Removed in favor of Hash#select
Removed Method Hash#indeces Removed in favor of Hash#select
Removed Method Object#id Removed in favor of Object#object_id
Removed Method Object#type Removed in favor of Object#class
Removed Method Object#to_a Removed in favor of Kernel#Array
Removed Method String#each Removed in favor of String#each_byte and
String#each_char
Removed Method Enumerable#enum_slice Removed in favor of Enumerable#each_slice
Removed Method Enumerable#enum_cons Removed in favor of Enumerable#each_cons
Removed Method Enumerable#enum_with_index Removed in favor of Enumerable#each_with_index
1.1 What’s Different Between Ruby 1.8 and 2.1? | 5
Trang 35Type 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
Removed Library finalize Replaced by objspace
Removed Library jcode UTF-8 support is now default, $KCODE is not necessary Removed Library wsdl No longer a standard library
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
Trang 36Type About Note
Removed Library xsd No longer a standard library
1.2 YARV (Yet Another Ruby VM) Bytecode Interpreter
is to tokenize and parse its syntax The MRI would mix parsing syntax with executingyour code, which ended up being prone to memory leaks and slow execution times TheYARV interpreter separates parsing with the running of your code
The bytecode interpreter takes the syntax tree and passes it to a virtual machine emulatorthat knows how to translate the bytecode into machine code The emulator is tuned andoptimized for the underlying hardware and knows how to translate instructions toPowerPC or x86 instructions The result in more efficient execution, less memory usage,and a faster language
# => [:program, [[:binary, [:@int, "1", [1, 0]], :+, [:@int, "1", [1, 2]]]]]
If you have any familiarity with Lisp, you may notice some similarities between a syntaxtree and any Lisp dialect For example, let’s replace the brackets with parenthesis andsee if it looks any more familiar
Trang 37to run nearly any Ruby code on any machine running Java.
See Also
• The YARV homepage (http://atdot.net/yarv/)
• The JRuby homepage (http://jruby.org)
• “How Ruby Executes Your Code” ( executes-your-code)
Trang 38http://patshaughnessy.net/2012/6/29/how-ruby-• The RubyVM documentation (http://www.ruby-doc.org/core-2.1.1/RubyVM/ InstructionSequence.html)
The most obvious syntax addition is for defining hashes Here is the new way you can
do it
old_way = {:foo => "bar", :one => 1}
new_way = {foo: "bar", one: 1}
You can also apply the same hash syntax when calling methods that take hashes. def some_method(hash = {})
is not deprecated, but the new way will save you a lot of time over your career with Ruby.This new syntax for defining hashes has also inspired new keyword arguments formethod definitions
Trang 39# ArgumentError: missing keyword: foo
It is interesting to note that def now returns the symbolic name of the method instead
of nil This allows you to string together private and public calls when defining yourclasses
The last big syntax addition is the new way to define procs
old_way = Proc.new { |a, b| a + b }
old_way.call(1, 2)
# => 3
Trang 40old_way = [:foo, :bar, :baz]
new_way = %i(foo bar baz)
The second smaller addition to Ruby syntax is a shortcut for defining Rational numbers. old_way = Rational(6, 5)
The new keyword arguments ability has complicated the way you can potentially define
a method, so here is an example of the most complicated method definition you canpossible do now that has every permutation in it
def foo(a, b="b_default", *c, d:, e: "e_default", **f, &g)
# do stuff
end
• a: required positional argument
• b: optional positional argument with a default value
• c: splat positional arguments that lack default values
• d: declared keyword argument
• e: declared keyword argument with a default value
• f: double splat keyword arguments that lack default values
1.4 Keyword Arguments | 11