标签:des style blog class code java
For windows you can download Ruby from http://rubyforge.org/frs/?group_id=167
for Linux tryhttp://www.rpmfind.net.
Enter the following into the file, "test.rb".
1 |
puts "Howdy!" |
At the C: prompt enter,
1 |
C :>ruby test.rb |
This produces:
1 |
Howdy! |
OK, daylight‘s burning, let‘s move on.
"puts" 写到屏幕上,并带有个换行,writes to the screen with a carriage return at the
end.
"print" 写到屏幕,但没有换行,does the same thing without the carriage
return.
"printf" 格式化输出到屏幕,formats variables like in C and Java 5.
1
2
3
4
5
6
7
8 |
puts "puts works" puts " with line breaks." print "print works" print " with no line breaks." printf("\n\nprintf formats numbers like % 7 .2f, and strings like %s. ",3.14156," me") |
This produces:
1
2
3
4
5
6 |
puts works with line breaks. print works with no line breaks. printf formats numbers like 3 . 14 , and
strings like me. |
Use "gets"
1
2
3 |
puts "What is your name?" $name
= STDIN .gets puts "Hi " + $name |
“def”用于定义函数,以“end”结束函数定义。
1
2
3
4 |
def welcome(name) puts "howdy #{name}"
# 必须包含在双引号内, #{ } 用来包含变量 end welcome( "nana" ) # traditional parens |
This Produces:
howdy nana
1
2
3 |
def welcome(name) puts "howdy #{name}"
# inside double quotes, #{ } will evaluate the variable end |
welcome "visitor" #look, ma, no parentheses
This Produces:
howdy visitor
如果没有参数,用不用括号都一样
1
2 |
"hello" .upcase() => "HELLO" "hello" .upcase => "HELLO" |
可以使用return语句
1
2
3
4
5 |
def multiply(a,b) product = a * b return
product end puts multiply( 2 , 3 ) => 6 |
函数定义内部最后一个表达式,默认做为返回值返回。
1
2
3
4 |
def mult(a,b) product = a * b end puts mult( 2 , 3 ) |
所以上面的product变量可以去掉了
1
2
3
4 |
def mult(a,b) a * b end puts mult( 3 , 3 ) => 9 |
Ruby lets you assign values to arguments which may, or may not be supplied as shown below:
1
2
3
4
5
6
7 |
def test(a= 1 ,b= 2 ,c=a+b) puts "#{a},#{b},#{c}" end test => 1 , 2 , 3 test 5
=> 5 , 2 , 7 test 4 , 6
=> 4 , 6 , 10 test 3 , 4 , 6
=> 3 , 4 , 6 |
Extra arguments是前面加一个星号的,并且要放在所有参数的最后
1
2
3
4
5 |
def test(a= 1 ,b= 2 ,*c) puts "#{a},#{b}" c. each {|x| print " #{x}, " } # We will learn about "each"
very soon. I
promise. end test 3 , 6 , 9 , 12 , 15 , 18 |
This produces:
3,6 9, 12, 15, 18,
1
2
3
4
5
6
7 |
def getCostAndMpg cost = 30000
# some fancy db calls go here mpg = 30 return
cost,mpg end AltimaCost, AltimaMpg = getCostAndMpg puts "AltimaCost = #{AltimaCost}, AltimaMpg = #{AltimaMpg}" |
Produces:
AltimaCost = 30000, AltimaMpg = 30
You can add methods to existing library classes.可以给已经存在的库中的类,增加新的方法。
1 |
if (mystring != null && mystring != "" ) |
给String类增加一个新的方法
1
2
3
4
5
6
7 |
class String def
NullOrEmpty? ( self
== nil || self == "" ) end end puts "test" .NullOrEmpty? puts "" .NullOrEmpty? |
Is this way cool? Yes. Is this very dangerous? Yes. Remember, Ruby is a chainsaw.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 |
# sample program showing special characters like comments # I‘m a comment line a = 1
#notice no semicolon and no type declaration b = 2 ; c = 3
#notice two statements on one line name = "Abraham \ Lincoln" # a line continued by trailing \ puts "#{name}" = begin I ‘m ignored. So am I . = end puts "goodbye" __END__ 1 2 3 4 Abraham Lincoln goodbye |
In Ruby, variables don‘t have a specific type associated with them.
All variables are objects, so we only play with pointers to those objects, and those pointers are type agnostic.
bat = "Louisville slugger" bat = 1.23
Like in Perl, single quotes and double quotes have different meanings.
Double quotes means "please interpret special characters in this string". Things like backslash n (‘\n‘) are converted to their typical values. The #{name} construct is converted to its value.
With single quotes, no special characters are interpreted.
Examples:
1
2
3
4 |
name= "Mike" puts "hi #{name}"
=>hi Mike puts "hi\n #{name}"
=> hi (carriage return )Mike puts ‘hi\n #{name}‘
=> hi\n #{name} (no substitutions are made since using single quote) |
The braces are optional for global and instance variables
1
2 |
$myname = "Ishmael" puts "hi #$myname"
=>hi Ishmael |
A great thing about Ruby is that numbers and strings are real objects.
1 |
1 . 5 .floor() => "1" |
This lets us do some cool things. Instead of
if( x > 7 && x < 12 ) { ... }
We can write
if x.between?(7,12) do ...
Ruby automatically increases the precision of variables
1
2
3 |
for i in 1 .. 1000 puts "2 ** #{i} = #{2**i}" end |
Produces:
2 ** 1 = 2 2 ** 2 = 4 2 ** 3 = 8 2 ** 4 = 16 2 ** 5 = 32 2 ** 6 = 64 2 ** 7 = 128 2 ** 8 = 256 2 ** 9 = 512 2 ** 10 = 1024 ... 2 ** 1000 = 107150860718626732094842504906000181056140481170553360744375038837035105112493612249319837881569585812759467291755314682518714528569231404 359845775746985748039345677748242309854210746050623711418779541821530464749835819412673987675591655439460770629145711964776865421676604298316526243868 37205668069376
Ruby will increase the precision of the number, or decrease it as needed:
1
2
3
4
5
6 |
x = 1000000 puts "#{x} " +x. class .to_s => 1000000
Fixnum x = x * x puts "#{x} " +x. class .to_s => 1000000000000
Bignum x = x / 1000000 puts "#{x} " +x. class .to_s => 1000000
Fixnum |
You can swap the values in variables without the use of a temp variable. Remember your first programming class: Swap the values in "i" and "j"? You had to use a "t" variable to store one of the values first. Not needed in Ruby.
1
2
3
4
5 |
i = 0 j = 1 puts "i = #{i}, j=#{j}" i,j = j,i puts "i = #{i}, j=#{j}" |
Produces:
i = 0, j=1 i = 1, j=0
1
2 |
nums = [ 1 , 2 . 0 , "three" ] puts nums[ 2 ] => three |
Ruby arrays, like all right-thinking collections, are zero based.
You can use negative indexes to start from the end of the array
1
2 |
nums = [ 1 , 2 . 0 , "three" , "four" ] puts nums[- 1 ] => four |
Using "-1" is so much more concise than "nums[nums.length()-1]".
1
2 |
[ 1 , 2 , 3 ].last => 3 [ 1 , 2 , 3 ].first => 1 |
To get the count, or size, of an array, use the "length" method.
1
2 |
mystuff = [ "tivo" , "nokia" , "ipaq" ] # make a string array puts mystuff.length => 3 |
Since many arrays are composed of single words and all those commas and quote marks are troublesome, Ruby provides a handy shortcut, %w:
1 |
mystuff = %w{tivo nokia ipaq} # make a string array |
To look at contents of an object use the "inspect" method. Even more convenient is to use "p" as a shorthand for "puts obj.inspect"
1
2
3
4 |
myarray = [ 1 , 2 , 5 , 7 , 11 ] puts myarray puts myarray.inspect p myarray |
Produces:
1 2 5 7 11 [1, 2, 5, 7, 11] [1, 2, 5, 7, 11]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28 |
# & is the intersection operator puts [ 1 , 2 , 3 ] & [ 3 , 4 , 5 ] # prints 3 # + is the addition operator puts [ 1 , 2 , 3 ]+ [ 3 , 4 , 5 ] # prints 1,2,3,3,4,5 # - removes items from the first array that appear in the second puts [ 1 , 2 , 3 ] - [ 3 , 4 , 5 ] # prints 1,2 # pop returns the last element and removes it from the array alpha = [ "a" , "b" , "c" , "d" , "e" , "f" ] puts "pop=" +alpha.pop # pop=f puts alpha.inspect # ["a", "b", "c", "d", "e"] # push appends elements to the end of an array alpha = [ "a" , "b" , "c" ] alpha.push( "x" , "y" , "z" ) puts alpha.inspect # ["a", "b", "c", "x", "y", "z"] # shift returns the first element and removes it from the array alpha = [ "a" , "b" , "c" , "d" , "e" , "f" ] puts "shift=" +alpha.shift # shift=a puts alpha.inspect # ["b", "c", "d", "e", "f"] # unshift appends elements to the beginning of an array alpha = [ "a" , "b" , "c" ] alpha.unshift( "x" , "y" , "z" ) puts alpha.inspect # ["x", "y", "z", "a", "b", "c"] |
This type of collection is also called a dictionary or an associative array.
1
2
3
4
5
6 |
cars = { ‘altima‘
=> ‘nissan‘ , ‘camry‘
=> ‘toyota‘ , ‘rx7‘ => ‘mazda‘ } puts cars[ ‘rx7‘ ] => mazda |
1
2
3
4
5
6
7
8
9 |
dict = {} # create a new dictionary dict[ ‘H‘ ] = ‘Hydrogen‘
#associate the key ‘H‘ to the value ‘Hydrogen‘ dict[ ‘He‘ ] = ‘Helium‘ dict[ ‘Li‘ ] = ‘Lithium‘ p dict[ ‘H‘ ] # prints "Hydrogen" p dict.length # prints 3 p dict.values # prints ["Lithium", "Helium", "Hydrogen"] p dict.keys # prints ["Li", "He", "H"] p dict # prints {"Li"=>"Lithium", "He"=>"Helium", "H"=>"Hydrogen"} |
You can also create Hashes with square brackets by prefixing with "Hash":
1
2 |
toppings = Hash [ "pancakes" , "syrup" , "Pizza" , "Pepper" , "Cereal" , "Sugar" ] puts toppings.inspect |
Produces:
{"Pizza"=>"Pepper", "Cereal"=>"Sugar", "pancakes"=>"syrup"}
The "each" method is a wonderful way to iterate over the keys
1
2 |
toppings = Hash [ "pancakes" , "syrup" , "Pizza" , "Pepper" , "Cereal" , "Sugar" ] toppings. each {|key, value| puts "#{key} points to #{value}" } |
Produces:
Pizza points to Pepper Cereal points to Sugar pancakes points to syrup
The "select" method populates a new array with members which meet a criteria
1
2
3
4 |
salaries = Hash [ "bob" , 10 . 9 , "larry" , 7 . 5 , "jimmy" , 6 . 0 , "jerry" , 6 . 5 ] salaries.inspect mySalaryArray = salaries.select{|name,salary| salary > 7 . 0 } puts mySalaryArray.inspect #prints [["larry", 7.5], ["bob", 10.9]] |
Ranges are composed of expr..expr or expr...expr. Two dots includes the last element, three dots excludes it.
1 |
( ‘a‘ .. ‘g‘ ). each { |letter| puts letter } |
Produces:
a b c d e f g
1 |
( 1 ... 3 ). each { |num| puts num } |
Produces only two numbers since "..." does not include the last element.:
1 2
if
1
2
3
4
5
6 |
if 1 < 2 rate = 0 . 28 else rate = 0 . 5 end puts rate |
1
2
3
4
5
6
7
8
9
10
11
12 |
grade = 10 school = case
grade when 0 .. 5 "elementary" when 6 .. 8 "middle school" when 9 .. 12 "high school" else "college" end puts "grade #{grade} is in #{school}" |
1
2
3 |
for i in 1 .. 4 puts "hi #{i}" end |
The ranges can of course have variables
1
2
3
4 |
top = 6 for i in 1 ..top puts "hi #{i}" end |
1
2
3
4
5 |
lines = IO .readlines( "data.txt" ) if lines.length < 100 exit 2 end puts lines.length |
iterates over code until a "break" or eternity ends
1
2
3
4
5
6 |
i= 0 loop do break
if i > 5 puts i i += 1 end |
These are just syntatic sugar.
The "if" clause may be placed at the end of a statement
1
2 |
balance = - 10 . 0 puts "Bankrupt"
if balance < 0 . 0 |
"unless" is placed at the end of a statement
1
2 |
balance = - 10 . 0 puts "Bankrupt"
unless balance > 0 . 0 |
"while" may be after its block
1
2
3
4
5
6 |
f= 2 puts f=f+ 2
while f < 10 => 4 => 6 => 8 => 10 |
1
2
3
4
5
6 |
i = 0 while
i < 5 i = i+ 1 puts i end |
1
2 |
n = 10 n.times { |i| print i} |
Produces:
0123456789
1
2 |
animals = %w(lions tigers bears) animals. each {|kind| print kind} |
lionstigersbears
1 |
( ‘m‘ .. ‘z‘ ). each
{|ch| print ch} |
mnopqrstuvwxyz
1
2 |
n= 0
; max= 7 n.upto(max) {|num| print num} |
01234567
Class definitions start with "class" and end with "end". Remember that class names start with a capital letter. Notice the syntax is "object.new" for creating an object and that the "initialize" method contains code normally found in the constructor. Here‘s a small example:
1
2
3
4
5
6
7
8 |
class
Person def
initialize(fname, lname) @fname
= fname @lname
= lname end end person = Person. new ( "Augustus" , "Bondi" ) print person |
Produces:
#<Person:0x257c020>
which is true, but not helpful.
1
2
3
4
5
6
7
8
9
10
11 |
class
Person def
initialize(fname, lname) @fname
= fname @lname
= lname end def
to_s "Person: #@fname #@lname" end end person = Person. new ( "Augustus" , "Bondi" ) print person |
Produces:
Person: Augustus Bondi
In Ruby subclassing is done with the "<" character
1
2
3
4
5
6
7
8
9
10
11 |
class
Employee < Person def
initialize(fname, lname, position) super (fname,lname) @position
= position end def
to_s super
+ ", #@position" end end employee = Employee. new ( "Augustus" , "Bondi" , "CFO" ) print employee |
Produces:
Person: Augustus Bondi, CFO
if we try to print the first name directly like
print employee.fname
CFOtest.rb:21: undefined method ‘fname‘
But why is that? We‘ve printed variables a zillion times up til now and it‘s always worked. What changed? Up until now we‘ve created variables in a program without classes (actually all are variables were members of a default object that were accessable inside itself). Now we are using real classes and that brings up the point of visibility of members outside the class. We now have to specify if a variable is open to the outside, like "public", "private", "protected", "internal" in other languages.
To grant access to read a variable we declare it after "attr_reader". attribute with the following:
1 |
attr_reader :fname , :lname |
print employee.fname => "Augustus"
To allow writing to a variable use "attr_writer",
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
class
Employee < Person def
initialize(fname, lname, position) super (fname,lname) @position
= position end def
to_s super
+ ", #@position" end attr_writer :position end employee = Employee. new ( "Augustus" , "Bondi" , "CFO" ) puts employee puts employee.fname employee.position = "CEO" puts employee |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 |
class Employee < Person def
initialize(fname, lname, position) super (fname,lname) @position
= position end def
to_s super
+ ", #@position" end attr_writer :position def
etype if
@position == "CEO" || @position
== "CFO" "executive" else "staff" end end end employee = Employee. new ( "Augustus" , "Bondi" , "CFO" ) employee.position = "CEO" puts employee.etype => executive employee.position = "Engineer" puts employee.etype => staff |
Strings can be compared to a regular expression with "=~". Regular expressions are surrounded by "//" or "%r{}". Anything but the two special values, "false" and "nil" are considered true.
Expression | Result | Description |
---|---|---|
/a/ =~ "All Gaul is divided into three parts" | 5 | finds the first "a" at position 5 |
%r{a} =~ "All Gaul is divided into three parts" | 5 | same thing with alternate syntax |
/ree/ =~ "All Gaul is divided into three parts" | 27 | finds "ree" at position 27 |
/^a/ =~ "All Gaul is divided into three parts" | nil | "^" implies at the beginning of a line. nil is false. |
/^A/ =~ "All Gaul is divided into three parts" | 0 | case-sensitive, remember that "0" is true |
/s$/ =~ "All Gaul is divided into three parts" | 35 | "$" implies at the end of a line |
/p.r/ =~ "All Gaul is divided into three parts" | 31 | "." matches any character |
And now to one of the coolest things about Ruby - blocks. Blocks are nameless chunks of code that may be passed as an argument to a function.
1
2
3
4
5
6 |
def whereisit yield yield yield end whereisit {puts "where is the money?" } |
Produces:
where is the money? where is the money? where is the money?
In the above example ‘{puts "where is the money?"}‘ is called a block. That chunk of code is passed to the method "whereisit" and executed each time the "yield" statement is executed. You can think of the "yield" being replaced by the block of code.
Here the method "cubes" takes the max value.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
def cubes(max) i= 1 while
i < max yield
i** 3 i += 1 end end cubes( 8 ) { |x| print x, ", " } => 1 , 8 , 27 , 64 , 125 , 216 , 343 , sum = 0 cubes( 8 ) { |y| sum += y} print "\nsum=" ,sum => sum= 784 product = 1 cubes( 8 ) { |z| product *= z} print "\nproduct=" ,product => product= 128024064000 |
Think of the "yield i**3" in the function cubes as being replaced with the block, ‘|x| print x, ", "‘. The value following the "yield" is passed as the value "x" to the block.
1
2
3
4
5
6
7 |
def employee(empId) #next 2 lines simulated from calling a database on the empId lastname = "Croton" firstname = "Milo" yield
lastname,firstname #multiple arguments sent to block end employee( 4 ) { |last,first| print "employee " , ": " ,first, " " ,last} |
Produces:
employee : Milo Croton
Even though rate is a local variable, it is used inside the block.
1
2
3
4
5
6 |
def tip(mealCost) yield
mealCost end rate = 0 . 15 mytip = tip( 10 . 0 ) { |cost| cost * rate } print "tip should be: " ,mytip |
Produces:
tip should be: 1.5
iterates through each item of a collection
1 |
[ 1 , 2 , 3 , 4 ]. each {|x| print x** 2 , " " } |
Produces:
1 4 9 16
returns the first item matching a logical expression
1
2
3 |
numbers = [ 1 , 3 , 5 , 8 , 10 , 14 ] firstDoubleDigit = numbers.detect {|x| x > 9 } print firstDoubleDigit => 10 |
returns all items matching a logical expression
1
2
3 |
numbers = [ 1 , 2 , 3 , 4 , 5 , 6 , 7 ]; evens = numbers.select{|x| x % 2
== 0 } p evens => [ 2 , 4 , 6 ] |
returns an array created by doing the operation on each element.
1
2 |
[ 1 , 2 , 3 , 4 ].collect{|x| x** 3 } => [ 1 , 8 , 27 , 64 ] [ "the" , "quick" , "brown" , "lox" ].collect{|x| x.upcase} => [ "THE" , "QUICK" , "BROWN" , "LOX" ] |
"inject" is the "fold" or "reducer" function in Ruby. "inject" loops over an enumerable and performs an operation on each object and returns a single value.
1
2
3
4
5
6
7
8
9
10
11
12
13 |
primes = [ 1 , 3 , 5 , 7 , 11 , 13 ]; #using "inject" to sum. We pass in "0" as the initial value sum = primes.inject( 0 ){|cummulative,prime| cummulative+prime} puts sum => 40 #we pass in no initial value, so inject uses the first element product = primes.inject{|cummulative,prime| cummulative*prime} puts product => 15015 #just for fun let‘s sum all the numbers from 1 to, oh, say a million sum = ( 1 .. 1000000 ).inject( 0 ){|cummulative,n| cummulative+n} puts sum => 500000500000 #you can do interesting things like build hashes hash = primes.inject({}) { |s,e| s.merge( { e.to_s => e } ) } p hash # => {"11"=>11, "7"=>7, "13"=>13, "1"=>1, "3"=>3, "5"=>5} |
1
2 |
file = File . new ( "t1.php"
) mytext = file.read |
1
2 |
lines = IO .readlines( "data.txt" ) puts lines[ 0 ] #prints the first line |
1
2
3
4 |
file = File .open( "res.txt" ) while
line = file.gets puts line end |
Or you can use the IO class
1 |
IO .foreach( "data.txt" ) { |line| puts line } |
You should ensure the file is closed as well.
1
2
3
4
5
6
7
8 |
begin file = File .open( "res.txt" ) while
line = file.gets puts line end ensure file.close end |
The following snippet of code reads a file which may have no line breaks and chops it into 80 character lines
1
2
3
4
5
6 |
require ‘readbytes‘ file = File . new ( "C:/installs/myapp_log.xml"
) while
bytes = file.readbytes( 80 ) print bytes+ "\r\n" end file.close |
Uses TruncatedDataError to grab the last few slacker bytes from the end.
1
2
3
4
5
6
7
8
9
10
11
12
13
14 |
# reads an xml file without line breaks and puts a line break before each ‘<‘ require ‘readbytes‘ file = File . new ( "C:/installs/SurveyDirector_log.xml"
) begin while
bytes = file.readbytes( 80 ) print bytes.gsub(/</, "\r\n<" ) end rescue
TruncatedDataError #the last read had less chars than specified #print the rest of the data. $! is the exception. # ".data" has the extra bytes print $!.data.gsub(/</, "\r\n<" ) ensure file.close unless
file. nil ? end |
In most languages when a method cannot be found and error is thrown and your program stops. In ruby you can actually catch those errors and perhaps do something intelligent with the situation. A trivial example:
1
2
3
4
5
6
7
8
9
10
11 |
class
MathWiz def
add(a,b) return
a+b end def
method_missing(name, *args) puts "I don‘t know the method #{name}" end end mathwiz = MathWiz. new puts mathwiz.add( 1 , 4 ) puts mathwiz.subtract( 4 , 2 ) |
Produces:
5 I don‘t know the method subtract nil
While the ruby program is loading, you can execute code inside a special block labeled "BEGIN" - pretty nifty. After the interpretor has loaded the code, but before execution, you can execute code in the "END" block.
1
2
3
4
5
6
7 |
puts "main program running" END
{ puts "program ending" } BEGIN
{ puts "I‘m loading" } |
Produces:
I‘m loading
main program running
program ending
Use the to_i and to_s methods
1
2 |
"3" .to_i #return an integer 3 .to_s # returns a string |
REXML goes standard with Ruby 1.8. Sample to print all "div" elements whose "class" attribute is set to "entry".
1
2
3
4 |
require "rexml/document" file = File . new ( "t0.xml"
) doc = REXML ::Document. new
file doc.elements. each ( "//div[@class=‘entry‘]" ) { |element| puts element } |
c:\home\mfincher>ruby -e ‘sleep 2‘ c:\home\mfincher>ruby -e ‘puts 3*4‘ 12 c:\home\mfincher>ruby -e ‘puts 3*4; puts 4*4‘ 12 16
Ruby offers a simple way to make a string substitution in many files all at once with a single line of code. The "-p" option loops over the files, the "-i" is the backup extension. With this command we are changing all the documentation from version 1.5 to 1.6, but the original files are renamed to ".bak".
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
C :\home\mfincher\ruby>more v2.txt Regarding version 1 . 5
... .... version 1 . 5
is easy to install C :\home\mfincher\ruby>ruby -pi.bak -e "gsub(/1.5/,‘1.6‘)"
v*.txt C :\home\mfincher\ruby>more v2.txt Regarding version 1 . 6
... .... version 1 . 6
is easy to install C :\home\mfincher\ruby>more v2.txt.bak Regarding version 1 . 5
... .... version 1 . 5
is easy to install |
1
2
3
4
5
6
7
8
9
10
11
12 |
#prints duplicate lines in sorted files in the file passed in as first arg file = File .open( ARGV [ 0 ]) lastLine = "" counter = 0 while
line = file.gets counter += 1 if
lastLine == line puts "#{counter-1}: #{line}#{counter}: #{line}\r\n" end lastLine = line end puts "done. Processed #{counter} lines" |
1
2
3
4
5
6
7
8
9 |
C :\home\mfincher>irb irb(main): 001 : 0 > puts "Hello World" Hello World => nil irb(main): 002 : 0 > a= 1 => 1 irb(main): 003 : 0 > a* 2 => 2 irb(main): 004 : 0 > |
1 |
echo ‘puts "hello"‘
| ruby |
1
2
3 |
require ‘uri‘ ... URI .escape( "some string..." ) |
Example of iterating over the filenames in a directory, using regular expression substitution in strings, and renaming files.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 |
#replaces any "funny" characters in a filename in the current directory with an underscore #if the new file name already exists, this skips it. Dir .foreach( "." ) { |f| print "testing \"#{f}\"" if
f =~ /[^\w\-\.]/ #filename contains something other than letters, numbers, _,-, or . puts "\r\n name with funny characters: #{f}" newName = f.gsub(/[^\w\.\-]/, "_" ) # \w is any word character, letter,num or _ if
File .exist?(newName) puts " File #{newName} already exists. Not renaming." else puts " renaming #{f} to #{newName}" File .rename(f,newName) end else puts " it‘s ok." end } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 |
ARGV . each
{|f| puts f counter = 0 file = File .open(f, "r" ) ftmp = f+ ".tmp" tmp = File .open(ftmp, "w" ) while
line = file.gets if
line =~ /pid= "2" / counter += 1 line = line.gsub(/pid= "2" /, "pid=\"#{f}:#{counter}\"" ) puts line end tmp.print line end file.close tmp.close puts "renaming #{ftmp} to #{f}" File .rename(ftmp,f) } |
command | description | example | result |
---|---|---|---|
global_variables | returns all global variables | ||
local_variables | returns all local variables | ||
sleep seconds | sleeps specified seconds | ||
rand | returns a random number between 0 and 1 | ||
rand(max) | returns int between 0 and max | ||
warn | like print, but writes to STDERR |
command | description | example | result |
---|---|---|---|
center | centers string | "City".center(20) | "________City________" |
ljust | left justifies | "State".ljust(30) | "State_________________________" |
rjust | right justifies | "State".rjust(30) | "_________________________State" |
include? | does the string include this substring | "this is a test".include?(‘is‘) | true |
gsub | global regex replacesments | "this is a test".gsub(/[aeiou]/,‘_\1‘) | th_s _s _ t_st |
tr | translates | "The greatest of these is".tr(‘aeiou‘,‘*‘) | Th* gr**t*st *f th*s* *s |
each | splits and iterates | "one:two:three".each(‘:‘){|x| puts x} | one: two: three |
1
2
3 |
puts DateTime.now #prints 2006-11-25T14:26:15-0600 puts Date.today #prints 2006-11-25 puts Time .now #prints Sat Nov 25 14:29:57 Central Standard Time 2006 |
require will let your access code from other files. ‘require‘ looks in directories specified in $LOAD_PATH to find the files. The environmental variable RUBYLIB can be used to load paths into $LOAD_PATH.
1
2
3
4
5 |
C :\home\mfincher\ruby>irb irb(main): 001 : 0 > p $LOAD_PATH [ "c:/opt/ruby/lib/ruby/site_ruby/1.8" , "c:/opt/ruby/lib/ruby/site_ruby/1.8/i386-msvcrt" , "c:/opt/ruby/lib/ruby/site_ruby" , "c:/opt/ruby/lib/ruby/1.8" , "c:/opt/ruby/lib/ruby/1.8/i386-mswin32" , "." ] => nil |
You can put a library like ‘startClicker.rb‘ in any of those directories and ruby will find it.
1 |
require ‘startClicker‘ |
With the "eval" method you can create your own interpreter language and run it during execution.
1
2
3
4
5
6
7
8 |
irb(main): 007 : 0 > a = 6 => 6 irb(main): 008 : 0 > b = 7 => 7 irb(main): 009 : 0 > eval "c=a+b" => 13 irb(main): 010 : 0 > puts c 13 |
You can find all the objects in your program of a particular type using ObjectSpace.each_object.
1
2
3
4
5
6
7
8
9
10
11
12 |
class Person def
initialize(name,age) @name
= name @age
= age end attr_reader :name end p = Person. new ( "Alfred" , 34 ) p2 = Person. new ( "Janie" , 31 ) ObjectSpace.each_object(Person) {|s| puts s.name } |
Produces:
Janie Alfred
Ruby comes right out of the box with a testing framework. Here‘s a quick example:
1
2
3
4
5
6
7
8
9
10 |
require ‘test/unit‘ class TestMe < Test::Unit::TestCase def
test_add s = 1
+ 1 assert_equal( 2 , s) end end |
This will get a particular page and print to the screen:
1
2 |
require ‘open-uri‘ |
1
2
3
4 |
#Reads first argument as file containing urls and prints them #usage: ruby wget.rb wget.txt require ‘open-uri‘ IO .foreach( ARGV [ 0 ]) { |line| open(line){ |f| print f.read } } |
Tk is a graphical subsystem used in languages like Perl and Tcl.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 |
#draws a single line on a big canvas require ‘tk‘ include Math TkRoot. new
do |root| title "Solo Line" geometry "600x600" canvas2 = TkCanvas. new (root) do
|canvas| width 600 height 600 pack( ‘side‘
=> ‘top‘ , ‘fill‘ => ‘both‘ , ‘expand‘ => ‘yes‘ ) points = [] end TkcLine. new (canvas2, 0 , 0 , 100 , 100 ) end Tk.mainloop |
Ruby comes with an REPL (Read Eval Print Loop) utility to let you try ruby interactively. ("inf-ruby.el" provides an internal shell in emacs for irb).
1
2
3
4
5
6
7
8
9 |
C :>irb irb(main): 001 : 0 > puts "hello" puts "hello" hello nil irb(main): 002 : 0 > Object .methods Object .methods [ "send" , "name" , "class_eval" , "object_id" , "new" , "singleton_methods" , "__send__" , "private_method_defined?" , "equal?" , "taint" , "frozen?" , "instance_variable_get" , "constants" , "kind_of?" , "to_a" , "instance_eval" , "require" , "ancestors" , "const_missing" , "type" , "instance_methods" , "protected_methods" , "extend" , "protected_method_defined?" , "eql?" , "public_class_method" , "const_get" , "instance_variable_set" , "hash" , "is_a?" , "autoload" , "to_s" , "class_variables" , "class" , "tainted?" , "private_methods" , "public_instance_methods" , "instance_method" , "untaint" , "included_modules" , "private_class_method" , "const_set" , "id" , "<" , "inspect" , "<=>" , "==" , "method_defined?" , ">" , "===" , "clone" , "public_methods" , "protected_instance_methods" , "require_gem" , ">=" , "respond_to?" , "display" , "freeze" , "<=" , "module_eval" , "autoload?" , "allocate" , "__id__" , "=~" , "methods" , "gem" , "method" , "public_method_defined?" , "superclass" , "nil?" , "dup" , "private_instance_methods" , "instance_variables" , "include?" , "const_defined?" , "instance_of?" ] irb(main): 003 : 0 > |
You can download RubyGems from http://rubyforge.org. Unzip the files (eg, C:\opt\ruby) then install by entering:
C:>cd C:\opt\ruby\rubygems-0.9.0 C:\opt\ruby\rubygems-0.9.0>ruby setup.rb all
You can use logger‘s methods "warn", "info", "error", and "fatal".
1 |
logger.info( "request.remote_ip" +request.remote_ip); |
to dubug applications it‘s convenient to use the console script
myapp>ruby script/console
You can use the debug() method inside web pages to dump info about an object.
<p>Thanks for visiting</p> <%= debug(@myobject) %>
Since your hosting company may upgrade the rails version you need to "freeze" the current version. The following copies all the 1.2.6 libraries from the shared directory to your own private one.
rake rails:freeze:edge TAG=rel_1-2-6
Find all records meeting a criteria
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
def
self .suitable_jokes(sort_key) if sort_key == "Newest" find( :all , :conditions
=> "suitable = \"1\"" , :order
=> "entry_date DESC" ) elsif
sort_key == "Worst" find( :all , :conditions
=> "suitable = \"1\"" , :order
=> "entry_date ASC" ) else find( :all , :conditions
=> "suitable = \"1\"" , :order
=> "current_rating DESC" ) end end |
The first argument to find can also be ":first" or ":last".
1
2
3
4
5
6 |
def
self .waiting_jokes() count( "suitable = \"0\"" ) end def
self .total() count( "suitable = \"1\"" ) end |
Find the total number of items
1 |
count = Joke.count |
Find the total number of items meeting a criteria
1 |
count = Joke.count([ "suitable = \"1\"" ]) |
The ":limit" and ":offset" options allow easy pagination.
To return the fifth page of items use the following:
1
2
3
4
5
6 |
find( :all , :conditions
=> "suitable = \"1\"" , :order
=> "current_rating DESC" , :limit
=> 10 , :offset
=> 40 ) |
1
2
3
4 |
def
getAverageRatingAndCount record = Rating.find_by_sql([ "select count(*) as count,avg(rating) as average from ratings WHERE joke_id = ?" ,id]); return
record[ 0 ].average.to_f , record[ 0 ].count.to_i end |
1
2
3
4 |
mydog = Dog.create( :name
=> "Fido" :breed
=> "Collie" ) |
Watir is a GUI testing tool written in Ruby. Here is a script to open Google and search for pictures of kittens.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 |
require "watir" ie = Watir:: IE . new
#create an object to drive the browser ie.goto "http://www.google.com/" ie.url == "http://www.google.com/" ie.link( :text , "Images" ).flash #flash the item text "Images" ie.link( :text , "Images" ).click #click on the link to the images search page ie.text.include? "The most comprehensive image search on the web"
#test to make sure it worked searchTerm = "kittens"
#set a variable to hold our search term ie.text_field( :name , "q" ).set(searchTerm) # q is the name of the search field ie.button( :name , "btnG" ).click # "btnG" is the name of the google button if ie.contains_text(searchTerm) puts "Test Passed. Found the test string: #{searchTerm}. Actual Results match Expected Results." else puts "Test Failed! Could not find: #{searchTerm}" end |
stolen from http://wiki.openqa.org/display/WTR/FAQ
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 |
#Watir script to show clicking a JavaScript popup box require "watir" require ‘watir\contrib\enabled_popup‘ require ‘startClicker‘ require ‘net/http‘ require ‘net/https‘ $ie
= Watir:: IE . new
#create an object to drive the browser if $ie .contains_text( "Log In" ) $ie .text_field( :name , "Login1$UserName" ).set( "fincherm" ) $ie .text_field( :name , "Login1$Password" ).set( "mitch" ) $ie .button( :name , "Login1$LoginButton" ).click end $ie .link( :text , "Baseline" ).click $ie .link( :text , "MoonManC" ).click def
setDdlPriority(priority) ddlPriority = $ie .select_list( :name
, /ddlPriority/) puts ddlPriority ddlPriority.select(priority) puts ddlPriority $ie .button( :name , "ctl00$btnSave" ).click_no_wait startClicker( "OK" , 4
, "User Input"
) sleep 1 end setDdlPriority( "2" ) setDdlPriority( "9" ) |
startClicker.rb:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 |
#method startClicker from http://wiki.openqa.org/display/WTR/FAQ def startClicker( button , waitTime= 9 , user_input= nil
) # get a handle if one exists hwnd = $ie .enabled_popup(waitTime) if
(hwnd) # yes there is a popup w = WinClicker. new if
( user_input ) w.setTextValueForFileNameField( hwnd, "#{user_input}"
) end # I put this in to see the text being input it is not necessary to work sleep 3 # "OK" or whatever the name on the button is w.clickWindowsButton_hwnd( hwnd, "#{button}"
) # # this is just cleanup w= nil end end |
Here is an example of connecting it to NUnit.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 |
using System; using System.Diagnostics; using System.Text.RegularExpressions; using NUnit.Framework; namespace SurveyDirector.Test.Watir { /// <summary> /// from http://www.hanselman.com/blog/IntegratingRubyAndWatirWithNUnit.aspx/// with small hacks from Liz Buenker /// </summary> public classWatirAssert { public static void TestPassed(string rubyFileName, string directoryPath) { string output = String .Empty; using (Process p = new
Process()) { p.StartInfo.UseShellExecute = false ; p.StartInfo.RedirectStandardOutput = true ; p.StartInfo.FileName = "ruby.exe" ; p.StartInfo.Arguments = rubyFileName + " -b" ; p.StartInfo.WorkingDirectory = directoryPath; p.Start(); output = p.StandardOutput.ReadToEnd(); p.WaitForExit(); } Console.Write(output); Trace.Write(output); Regex reg = new
Regex(@ "(?<tests>\d+) tests, (?<assertions>\d+) assertions, (?<failures>\d+) failures, (?<errors>\d+) errors" , RegexOptions.Compiled); Match m = reg.Match(output); try { int tests = int.Parse(m.Groups[ "tests" ].Value); int assertions = int.Parse(m.Groups[ "assertions" ].Value); int failures = int.Parse(m.Groups[ "failures" ].Value); int errors = int.Parse(m.Groups[ "errors" ].Value); if
(tests > 0
&& failures > 0 ) { Assert.Fail( String .Format( "WatirAssert: Failures {0}" , failures)); } else
if (errors > 0 ) { Assert.Fail( String .Format( "WatirAssert: Errors {0}" , errors)); } } catch ( Exception
e) { Assert.Fail( "WatirAssert EXCEPTION: "
+ e.ToString()); } } } } |
The above code would be used by something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
using System; using NUnit.Framework; namespace SurveyDirector.Test.Watir { [TestFixture] public classWatirTest { private static readonly string testDir = Utilities.Properties.baseDir + "\\Test\\Watir" ; public WatirTest() { } [Test] public void Sd01Test() { WatirAssert.TestPassed( "sd01_test.rb" ,testDir); } [Test] public void Sd02Test() { WatirAssert.TestPassed( "sd02_test.rb" ,testDir); } } } |
"Ruby is a language for clever people." -Matz
"Ruby is the
perlification of Lisp." -Matz
"Type Declarations are the Maginot line
of programming." -Mitch Fincher
标签:des style blog class code java
原文地址:http://www.cnblogs.com/lizunicon/p/3721085.html