1. Trang chủ
  2. » Công Nghệ Thông Tin

Addison wesley ruby phrasebook sep 2008 ISBN 0672328976 pdf

218 149 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 218
Dung lượng 1,52 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

String to Array and Back Again 10 String to Regular Expression and Back Again 12Floating-Point, Integer, and Rational Numbers 15 Checksumming a String MD5 or Otherwise 31... Without the

Trang 2

1 Converting Between Types 5

10 Rapid Applications Development

13 Working with Networking and

16 Working with Ruby Packages 185

Trang 4

Copyright © 2009 by Pearson Education, Inc.

All rights reserved No part of this book shall be reproduced,

stored in a retrieval system, or transmitted by any means,

electronic, mechanical, photocopying, recording, or otherwise,

without written permission from the publisher No patent

liability is assumed with respect to the use of the information

contained herein Although every precaution has been taken in

the preparation of this book, the publisher and author assume

no responsibility for errors or omissions Nor is any liability

assumed for damages resulting from the use of the information

Printed in the United States of America

First Printing August 2008

Trademarks

All terms mentioned in this book that are known to be

trade-marks or service trade-marks have been appropriately capitalized.

Pearson Education, Inc cannot attest to the accuracy of this

information Use of a term in this book should not be regarded

as affecting the validity of any trademark or service mark.

Warning and Disclaimer

Every effort has been made to make this book as complete

and as accurate as possible, but no warranty or fitness is

implied The information provided is on an “as is” basis

The author and the publisher shall have neither liability nor

responsibility to any person or entity with respect to any loss or

damages arising from the information contained in this book.

Bulk Sales

Pearson Education, Inc offers excellent discounts on this book

when ordered in quantity for bulk purchases or special sales.

For more information, please contact

U.S Corporate and Government Sales

Trang 5

String to Array and Back Again 10 String to Regular Expression and Back Again 12

Floating-Point, Integer, and Rational Numbers 15

Checksumming a String (MD5 or Otherwise) 31

Trang 6

3 Working with Collections 35

Modifying All the Values in an Array 42

Building a Hash from a Config File 44 Sorting a Hash by Key or Value 45 Eliminating Duplicate Data from Arrays (Sets) 46

Inspecting Objects and Classes 50 String Presentation of Objects 50 Ruby-Style Polymorphisms (“Duck Typing”) 51

Determining Interactive Standard Pipes 62 Synchronizing STDERR with STDOUT 63 Capturing the Output of a Child Process 64

Creating a Secured Password Prompt 66

Searching and Seeking Large File Contents 70

Trang 7

When to Use Binary Mode (Win32) 73

Copying, Moving, and Deleting Files 74

Sorting the Contents of a File 80

Adding Users from a Text File 88 Delete All the Files Just Extracted 89

Trang 8

Attaching a Signal Handler to a Qt

Attaching Signal Handlers to Qt Designer

Representing Data Graphically 138

Opening (and Closing) a MySQL Database

Trang 9

Serializing Objects with YAML 156 Network Objects with Distributed Ruby 158

Typographic Conventions Used 177 Overriding Method Signatures in

Hiding a Module, Class, or Method 180 Providing Program Usage Help 180 Generating HTML Documentation 182 Generating and Installing Documentation for ri 183

Packaging Your Module with Hoe 189

Distributing Your Module on RubyForge 191

Trang 10

About the Author

Jason Clinton has been working in the computerindustry for more than a decade He is activelyinvolved in the Kansas City Ruby Users Group(KCRUG), serving as administrator of the group’swebsite and mailing list, and he teaches a communityclass on Linux at University of Missouri-Kansas City.Clinton uses Ruby daily in system administration anddevelopment for Advanced Clustering Technologies, aLinux Beowulf cluster integrator

Trang 11

Without the Pragmatic Programmers’ freely available

first edition of Programming Ruby, I would have never

discovered the wonderful world of Ruby The Pickaxebooks and the great Ruby community make projectslike this one possible

Thanks to my loving partner, Brandon S.Ward, for hisinfinite patience while I was working on this book

Trang 12

We Want to Hear from You!

As the reader of this book, you are our most important

critic and commentator.We value your opinion andwant to know what we’re doing right, what we could

do better, what areas you’d like to see us publish in,and any other words of wisdom you’re willing to passour way

You can email or write me directly to let me knowwhat you did or didn’t like about this book—as well aswhat we can do to make our books stronger

Please note that I cannot help you with technical problems related to the topic of this book, and that due to the high volume of mail I receive, I might not be able to reply to every message.

When you write, please be sure to include this book’stitle and author as well as your name and phone number or email address I will carefully review yourcomments and share them with the author and editorswho worked on the book

Email: feedback@developers-library.info

Mail: Mark Taber

Pearson Education, Inc

800 East 96th Street

Indianapolis, IN 46240 USA

Reader Services

Visit our website and register this book at

informit.com/register for convenient access to anyupdates, downloads, or errata that might be availablefor this book

Trang 13

Audience

You can find some great Ruby books on the market

If you are new to Ruby, a friend or someone on theInternet has probably already listed some favorite

Ruby books—and you should buy those books But

every book has its niche: Each attempts to appeal to acertain need of a programmer

It is my belief that the best thing this book can do for

you is show you the code I promise to keep the chat to a

minimum, to focus instead on the quality and quantity

of actual Ruby code I’ll also keep as much usefulinformation in as tight a space as is possible

Unlike any other book on the market at the time ofthis writing, this book is intended to be a (laptop-bag)

“pocket-size” resource that enables you to quicklylook up a topic and find examples of practical Rubycode—a topical quick reference, if you will In each ofthe topics covered, I try to provide as thorough anapproach to each task as the size allows for; there’s not

as much room for coverage of topical solutions as there

is in much larger books with similar goals, such as The

Ruby Way, 2nd Edition (Sams, 2006), by Hal Fulton.

Because of this, other issues that are often given equalpriority are relegated to second For instance, this is

Trang 14

not a tutorial; the code samples have some explanation,but I assume that you have a passing familiarity withthe language Also, when possible, I try to point outissues related to security and performance, but I make

no claim that these are my highest priority

I hope that you find this book a useful tool that you

keep next to your keyboard whenever you are

phrase-mongering in Ruby.

How to Use This Book

I have not intended for this book to be read cover tocover Instead, you should place your bookmark at theTable of Contents so you can open the book, find thetopic you are programming on at the moment, and goimmediately to a description of all the issues youmight run into

The content in the book is arranged by topic instead

of Ruby class.The benefit is that you can go to oneplace in this book instead of four or five areas inRuby’s own documentation (Not that there’s anythingwrong with Ruby’s documentation It’s just that some-times you are working with several classes at a timeand, because Ruby’s docs are arranged by class, youhave to jump around a lot.)

Trang 15

Code snippets that appear in normal text are in italics.

All other code blocks, samples, and output appear as

follows:

# code sample boxes.

Parentheses are optional in Ruby in some cases—the

rule is: you must have parentheses in your method call if

you are calling another function in your list of

parame-ters, or passing a literal code block to the method In allother cases, parentheses are optional Personally, I’m a

sucker for consistency but one of the indisputable

strengths of Ruby is the flexibility of the syntax

In an attempt to have consistency between this book

and others, I will (reluctantly) use class_method()to

refer to class methods, ::class_variableto refer to classvariables,#method()to refer to instance methods, and

finally#varto refer to instance variables.When

refer-ring to variables and methods which are members of

the same class, I’ll use the appropriate @variableand

@@class_varriable

I know that some people might find these two rules

annoying—especially those coming from languages

that use the ‘::’ and ‘.’ notation everywhere In all ticality, you will never be so consistent—and rightfully

prac-so One of Ruby’s strengths is that there is a ton of

flexibility In fact, this flexibility has helped make Ruby

on Rails so popular.This allowed the creators of Rails

to make what appears to be a domain-specific language (a

language well-suited for a specific kind of work) for

web development But really, all that is going on is a

variation on Ruby syntax And this is one of the manyreasons that Ruby is more suitable for a given problemthan, say, Python Python’s rigidity (“there should be

Trang 16

one—and preferably only one—obvious way to do it”)doesn’t lend itself to DSL, so the programmers in thatlanguage are forced to use other means (which might

or might not turn out to be unpleasant)

I always use single quotes (') in Ruby code unless I

actually want to make use of the double-quote (")features (interpolation and substitution)

I always put the result of the evaluation of the ment (or block) on the next line with a proceeding

state-#=>, similar to what you would find if you were usingirb or browsing Ruby’s documentation

Comments on executable lines of code start with #and

are in italics to the end of the comment Comments on

#=>lines are in parentheses and are in italics.

Acknowledgments

Without the Pragmatic Programmers’ freely available

1st Edition of Programming Ruby, I would have never

discovered the wonderful world of Ruby.The Pickaxebooks and the great Ruby community are what makeprojects like this one possible

Thanks to my loving partner, Brandon S.Ward, for hisinfinite patience while working on this book

Reporting Errata

Readers will almost certainly find topics that they wishwere covered which we were overlooked when plan-ning this book I encourage you to please contact usand let us know what you would like to see included

in later editions Criticisms are also welcome Contactinformation can be found in the front-matter of thisbook

Trang 17

to yourself as you are coding: “everything is an object,everything is an object, ”.That’s the rule to swim orsink by in Ruby Absolutely everything around is anobject: an instance of a class.

Also, keep in mind that the rigidness that comes withstatically typed languages is relaxed Methods (general-ly) do not check to see whether an object that theyare working with is an instance of a particular class.For example, the #putsmethod will accept any objectwhich responds to a #to_smethod call So, if yourobject implements #to_s, you can use #puts.This is

Trang 18

called “duck typing” – you’ll see more discussion aboutthis throughout the book.

Number from a String

Float If you want the input to decide whether it getsstored as a Float or Fixnum, do this instead:

class String

def to_real

if self.include? '.'

self.to_f else

self.to_i end

Trang 19

Number to Formatted String

Number from a String

123.to_s

#=> "123"

(123.0).to_s

#=> "123.0"

Often a simple conversion from IntegerorFloatto

Stringwill do—as in above

However, Ruby also has the sprintfstyle of String

formatting built in C programmers will be familiar

with this Many Stringformatting codes exist; I coverjust the numeric ones here in Table 1.1; refer to Table

2.1 for an additional list of the escape codes that can

be used for formatting Strings Also try man sprintf

orri Kernel.sprintf from a terminal on your

favorite*nix (or Cygwin on Windows) for complete

documentation of this feature

Here are some examples of using sprintf():

'The price is: %10d' % 123

#=> "The price is: 123" (space padding)

'The price is: %10.2f' % 123

#=> "The price is: 123.00"

Trang 20

XorX space,#,+,-,0,*d Integer argument is

converted to hexnotation.dforcesuppercase AtoF

o space,#,+,-,0,*d Integer argument is

converted to octalnotation

b space,#,+,-,0,*d Integer argument is

converted to binarynotation

f d.d, space,#,+,-, Float argument is

0,*d converted to floating

notation with a ing zero before num-bers less than 1orgreater than -1

Trang 21

lead-Numeric Arguments Explanation

is less than -4orgreater than or equal

to the precision.G

forces uppercase E

unknown author, printf man page, 2000

Table 1.2 gives an explanation of what each of these

arguments does

Table 1.2 Numeric SprintF Arguments

d.d The first dis the width, the last dis

an integer representing the precision

of the floating point rendering A

-preceding this argument causes leftjustification

space Pad width with spaces

# Use alternate notation for hex, octal,

Trang 22

Table 1.2 Continued

*d dmust be an integer indicating

the width of the numerical representation

Note that *is assumed for the first nonzero numberencountered in the argument list

String to Array and

surpris-to Table 1.3 for a list of ranges that can be used inside

String.[]

Trang 23

Here are some results that you might not expect at

#=> "ar" (no out of range error)

Table 1.3 String Slicing Operators

String Ranges Positions (Counting starts at

0, Negative Numbers Count Position from the End)

S[{start} {end}] {start}includes the

character;{end}includesthe character

S[{start} {end}] {start}includes the

character;{end}excludesthe character

S[{start}, {count}] {start}includes the

character;{count}positionsfrom start to include Use 1

to get a one-character string.You can also assemble a Stringfrom an Arrayof

Strings:

['this','is','a','test'].join ' '

#=> "this is a test"

Also see the subsection “Replacing Substrings” in

“Working with Strings” for information about

replac-ing parts of Stringsusing slicing operators

String to Array and Back Again

Trang 24

String to Regular Expression and Back Again

inter-asYYYY-MM-DDorMM/DD/YY You can make a Regexp

object from this as follows:

Regexp.new gets.chomp.gsub(%r{[^/]}, '\d')

In plain English, this means: “Get a line of input, stripwhite space from the ends, replace all occurrences ofcharacters that are not ^or/with the String \d(sin-gle quoted), and convert the resulting Stringobjectinto a Regexpobject.” Note that %r{}is another way

of writing a regular expression literal—in this case, Iused it to avoid having to escape the /

Conversely,Stringrepresentations of the content of a

Regexpcan be made

Note that the last form listed at the beginning of thissubsection is in alternate notation which is more

Trang 25

human-readable; also note that feeding this alternate

notation back into Regexp.newmight not result in thesameRegexpobject

See the subsection “Searching Strings” in “Working

with Strings” for more on this topic

Array to Hash and Back Again

Array to Hash and Back Again

Hash[*[1,2,3].zip([4,5,6]).flatten]

#=> {1=>4, 2=>5, 3=>6}

{ 'foo' => 1, 'bar' => 2, 'baz' => 3 }.keys

#=> ["baz", "foo", "bar"]

{ 'foo' => 1, 'bar' => 2, 'baz' => 3 }.values

#=>[3, 1, 2]

{ 'foo' => 1, 'bar' => 2, 'baz' => 3 }.to_a()

#=> [["baz", 3], ["foo", 1], ["bar", 2]]

Above, two ordered Arrays, one with your keys—1, 2,and 3—and another with your values—4, 5, and 6—

are zipped together, flattened, and then splatted to

make the Array compatible with the Hash.[] class

method.This makes the values from the Array become,

one, the key and, the other, the value.

If you have an Arrayand you want to initialize all of

the keys of a new Hashbut not yet set the values, a

clever trick is to zip the Array of keys with an empty

Array:

Hash[*%w{a b c}.zip([]).flatten]

#=> {"a"=>nil, "b"=>nil, "c"=>nil}

Similarly, you can assign the Array’s index to the value

instead of nil – this requires an interative

approach

Trang 26

#=> {1=>nil, 2=>nil, 3=>nil}

Conversely, you can get the keys and values out of the

Hashin a number of ways including those short ods listed at the beginning of this section

meth-However, you might also want to walk through the

Hashand get an Arrayfrom keys or values that meetcertain criteria:

{ 'foo' => 1, 'bar' => 2, 'baz' => 3 }.select do |k, v|

Trang 27

Array to Set and Back Again

Floating-Point, Integer , and Rational Numbers

require 'set'

['foo', 'bar', 'baz'].to_set

#=> #<Set: {"baz", "foo", "bar"}>

Set.new(['foo', 'bar', 'baz']).to_a

#=> ["baz", "foo", "bar"]

ASetcan be thought of as a Hashwith no values (in

fact, it uses a Hashfor storage) As you can see,

con-verting to a Setfrom an Arrayis much easier than

Trang 28

For the most part, numbers behave in Ruby exactly asthey do in other languages.You might be interested intwo exceptions, though:

If the Integerrepresentation of a number is too large

to store in the host machine’s CPU registers (largerthan 32 bits on x86), the Integerrepresentation isstored in a Bignumobject instead of a Fixnumobject.The difference between the two is that Bignumallowscomputation on very large (or very negative) numbers

at the cost of computational overhead Note that Rubyuses 1 bit for the sign and 2 more bits for the tag (usedfor internal bookkeeping)

(2**29).class

#=> Fixnum

(2**30).class

#=> Bignum

Ruby also supports storing numbers in a Rational

object that implements the normal arithmetic

Trang 29

A Word on Boolean true and false

In Ruby, anything that is not either false or nil is

considered true —even 0 (zero) Let me say that again:

0 evaluates to true If you want to say that something

evaluates to false , you must explicitly state it If your

method needs to return true as the result of

some conditional test , just return the test as result

as the return value Remember, the last evaluation in a method is the return value.

As an interesting side note, in Ruby, any time you write out true or false in your code, you are referring to

singleton instances of the TrueClass and

FalseClass , respectively So, even true and false

have member methods, and variables and respond to

method calls.

Floating-Point, Integer , and Rational Numbers

Trang 31

The following subsection and the next two subsectionsare closely related I first briefly present the simplesearching functions that accept Stringsas parameters;then I dive right in to regular expressions.

Trang 32

#=> 3 (2 "o"s and 1 "b")

'foobar'.count 'ob', 'o'

#=> 2 (only "o" appeared in both parameters) 'foobar'.index 'ob'

by much)

In the middle two examples,#countis used to returnthe number of occurrences of a particular string.Additional parameters to #countare intersected on a

character basis (Intersection is a term from set logic It

means to only include those elements which occur inboth sets In this case, an “element” is a character.) Thismethod is not yet Unicode safe

Finally, in the last two examples,#indexreturns theposition—in count-from-zero notation—of the firstoccurrence of either a String or the numerical code of

a character.You can use #rindexto find the index ofthe last occurrence

Trang 33

You can also walk through a String,File, or IOStream

performing a search Let’s say that you want to write a

simple config file parser that places each config

vari-able and its value in a Hash:

The code at #is executed only if =is present See the

subsection “Parsing a Simple Config File,” in Chapter

7, “Manipulating Text,” for a much more complete

example of this

Searching Strings with Regular

Expressions

Searching Strings with Regular Expressions

"The time is: 12:34:54\n".match

This topic is huge—entire books are devoted to

regu-lar expressions Perhaps the best one is Mastering

Regular Expressions (O’Reilly, 2002), by Jeffrey E F.

Friedl If your job includes working with a lot of cleartext, I highly recommend that you pick up this

resource and keep it within reach

Trang 34

Here I cover ways in which you can use Regexpobjects

to search text in Ruby (it’s not a review of the regularexpression language)

When performing a Regexpmatch in Ruby, any ()groupings within the Regexpare set to the (thread-local) global variables $1to$9in the order they appear

in the Regexp

The#matchmethod returns a MatchDataobject for the

first match in the Stringand also sets the global variable

$~to the same object Here’s what a MatchDatahas init:

m = "The time is: 12:34:54\n".match

Trang 35

"The time is: 12:34:54\n".split(/:\s/)

#=> ["The time is", "12:34:54\n"]

"Setting #{ary[0]} is currently set to #{ary[1]}."

#=> "Setting some_variable is currently set to

some_value."

"You are currently looking at #{ary[0].tr('_', '

')}."

#=>"You are currently looking at some variable."

As mentioned in the section “String to Array and BackAgain,” in Chapter 1, “Converting Between Types,”

Stringscan be treated like Arraysof characters in

many respects.This includes replacements such as

above

In the last two examples above, double-quoted Strings are used to evaluate "#{}"clauses within them and

interpolate the result of the evaluation.You can do

pretty much anything inside a "#{}" In the above

examples I show array access and even a #tr

method call.

A somewhat more obscure function, #tr allows you to

do a character-wise replacement:

Trang 36

'You are currently looking at a string.'.tr 'aeiou', '_'

#=> "Y _r_ c_rr_ntly l k_ng _t _ str_ng." 'You are currently looking at a string.'.tr 'aeiou', 'uoiea'

#=> "Yea uro carrontly leeking ut u string."

The first example replaces all vowels with an “_” acter; the second switches each vowel for anothervowel.See the subsection “Sanitizing Input,” later

char-in this chapter, for another example of uschar-ing #tr and a discussion of how #tr parameters work.

Replacing Substrings using SprintF

#=> "I received a couple of strings: one, two" 'I received %25p' % [['an', 'array']]

#=> "I received [\"an\", \"array\"]" 'I received %-25p' % [['an', 'array']]

#=> "I received [\"an\", \"array\"] "

As with numbers, you can also apply sprintfstyleformatting using the “%”operator.Table 2.1 gives theallowed arguments

Trang 37

Table 2.1 String SprintF Codes

String Arguments Explanation

Argument Allowed

repre-senting character code

to.inspect()And Table 2.2 lists what those arguments do

Table 2.2 String SprintF Arguments

Argument Explanation

*d dmust be an integer Specifies the

width of the field

- Left justification

I should also briefly mention a somewhat obscure

fea-ture of sprintf:You can use (position)$positional

notation to access a specific entry in the array provided.Somewhat annoyingly, however, the notation for this

access counts starting at 1instead of 0(asArraysdo):

'Hi %1$s! Today you turn %2$d! Happy birthday,

Trang 38

'The current time is: 12:34:21'.sub(

/(\d\d):(\d\d):(\d\d)/, '\1\2\3')

#=> "The current time is: 123421"

Replacing Substrings using Regular Expressions

Again, you can use regular expressions for some erful functions Use \1to\9to interpolate the group-ing parentheses’ results from the match to yourreplacement Use .#gsubinstead of .#subto replace alloccurrences in a String.

pow-In the example above, the entire phrase “12:34:21” ismatch and replaced with the subgroups 1-3 with no

“:”s between them Alternatively, you could simplyreplace any occurrence of “:” appearing between digits.This could be written like this:

'The current time is: 12:34:21'.gsub(

/(\d):(\d)/, '\1\2')

#=> "The current time is: 123421"

Working with Unicode

#!/usr/bin/ruby -wKu

' цитрус'.scan(/./) { |b| print b, ' ' }

Produces:

ц и т р у с

Ruby accepts source files encoded in UTF-8 Just to

be safe, include the -Kucommand-line option in your

Trang 39

shebang line to ensure that this is properly interpreted

on other OSs and other locales.The modified shebangline is the first line in the code sample above

Ruby itself is not yet fully internationalized For

instance, Ruby is unaware of the multibyte nature of

UTF-8 beyond the first 255 character codes So

#each_byte must be used with care when dealing withinternational strings; for example, it will not work on

any non-Latin languages:

puts " цитрус" # output directly to buffer

"цитрус".each_byte { |b| print(""<<b, ' ') }

Produces:

цитрус

? ? ? ? ? ?

Instead, use the Regexp engine to iterate over these

characters (it is UTF-8 aware).The code to do this is

the code sample at the beginning of this section

In general, use the Regexpengine for slicing and

matching when you’re working with Unicode Other

than that,Stringswith Unicode content should

behave exactly as you expect them to

Sanitizing Input

Sanitizing Input

new_password = gets

if new_password.count '^A-Za-z._' != 0 then

puts "Bad Password"

else

#do something like in subsection “Encrypting a

String"

end

Trang 40

Let’s say that you want to write a password changer for

*nix (perhaps storing to an LDAP back end) At a

login prompt, you can use almost all characters in a

password that you can generate at a keyboard But thefew that you can’t use might give your users a

headache when they discover that they can’t log inagain after changing their password In an effort tomake your life easier, you could write a passwordchanger that restricts the password to alphanumericand a few of its friends.String#count, as applied above,can help you do just that

This works by using a special syntax that’s shared by.#count,.#tr,#delete, and #squeeze A parameterbeginning with ^negates the list; the list consists ofany valid characters in the active character set and maycontain ranges formed with - If more than oneparameter list is given to these functions, the lists ofcharacters are intersected using set logic—that is, onlycharacters in both lists are used for filtering

For other types of sanitation, you might also want tosimply replace all “evil” characters with _(such as perhaps from a CGI form post):

evil_input = '`cat /etc/passwd`'

evil_input.tr('./\`', '_')

#=> "_cat _etc_passwd_"

Working with Line Endings

When dealing with clear text from the three main OStypes, you will encounter what is perhaps their oldestfile format fragmentation (see Table 2.3)

Ngày đăng: 19/03/2019, 10:44

TỪ KHÓA LIÊN QUAN