1.print打印语句时不带换行符,puts带换行符,p用于そのまま把内容打出来,对程序员友好。
gets()用于获取用户输入
2.双引号字符串可以插入变量或者表达式,“hello #{name} #{10 * (1 + 2)}”
3.注释是#,多行注释以=begin开始,=end结尾
4.定义一个方法
def add(param1, param2) return param1 + param2 end
#可变参数以及数组转参数列表
def addAll(param1, *param2) if param2.size == 0 param1 else param1+ param2.inject { |sum, ele| sum + ele } end end puts addAll(10) puts addAll(10,12,34,45) puts addAll(10,*[12,34,45]) #dereference array into params
5.字符串转换成数字string.to_i,string.to_f,如果字符串不是数字,那么调用这些方法将返回0
6.
if () then //then大多数时候可以不需要,只要在if语句的所有内容写在同一行时才需要
#statements
else
#statements
end
7.定义一个类时,init方法是她的构造函数,to_s=toString, class Dog < Animal表示继承
使用p方法查看元素内部表示
8.利用attr_accessor声明getter,setter
class Animal attr_accessor :name attr_accessor :gender def to_s super.to_s + " #{@name}"; end end
同样也可以手工自己写
def gender() return @gender end def gender=(gender) @gender = gender end
9.ruby支持直接调用系统命令,返回值为字符串类型
puts `ps -ef`
10.
数组和js没什么大区别
for i in arr
end
[1, 2, 3].each do |i| puts i end
[1,2,3].each_with_index do |elem,index|
end
[1,2,2,3].delete(2) -> [1,3]
[1,2,2,3].delete_at(2) -> [1,2,3] 等价于 [1,2,2,3].slice!(2)
slice!方法重载组可以按照范围删除 slice!(1..3)
或者按照起始位置和长度删除slice!(1,3)
[10,20,30].delete_if{|x|
x > 20
}
arr.uniq,arr.uniq!去重
[1,2,3].index(2) #返回2的index位置,如果元素不存在返回nil
[1,2,3].include?(2) #是否存在
arr = [1,2,3,4,5]
arr[1,4] #从2开始获取,长度为4
arr[1..4] #从2开始获取,到4
arr[1...4] #从2开始,4为开区间
可以使用
arr[1..10] = [...]
arr[1,3] = [3,4,5]等方法修改数组中间的值
使用
arr[1,0] = [89,101] 在1处插入2个值
arr.values_at(1,3,5) 获取数组1,3,5处的值所组成的数组,和lodash的_.at(arr,[1,3,5])很像
把字符串转变为数组
y = %w( this is an array of strings )生成数组["this","is"....]
注意这种方式的话,字符串不能包含空格,比如说
y = %w(this "is a")
可能我们的意图是["this","is a"],但实际结果是
["this","\"is","a\""]
#reduce
arr = (1..10).to_a puts arr.inject { |sum, x| sum += x }
11.hash
hash = Hash.new #或者hash={} hash = { "name" => "sakop", #这种写法key要加引号 age: 27 #s:gender => "male" }
hash.default=12345;#如果某个键没有被设置,那么对他get时将返回12345 p hash
12.array
[12,34,56] & [34] -> [34]
[12,34,56] + [34] -> [12,34,56,34] # +是安全的,不会改变操作数组,而arr1.concat(arr2)会把合并后的数组写入arr1
[12,34] << 56 -> [12,34,56]
[12,34].reverse -> [34,12]
p [56, 78, 34].sort.reverse -> [78,56,34][1,nil,0,false,[],{}].compact #只会去除nil,而lodash的该方法会删除boolean值为false的对象除此之外,array还有empty?,include?,reverse等方法,默认情况下这些方法不会改变数组本身,如果需要改变本身的话,需要在方法名字后加入感叹号。13.Ruby的module1.用作工具方法管理库module SakopModule def ok puts "ok " + self.to_s end module_function :ok #必须这么暴露,不然外头访问不到 PI = 3.14 end2.可以解决多继承,假设一把剑它既属于武器有可能属于宝藏,由于ruby不支持多继承,所以暂且让Sword类继承自Weapon,然后再宝藏模块中定义如下方法module Treasuredef pricereturn @price * "999999999"endend然后再Sword中包含他class Sword < Weaponattr_accessor :price@price = 10include Treasureend这样就可以调用定义在Treasure中得price方法了Sword.new.price这种过程有点类似duck typing另外,include Treasure会假设Treasure模块和当前类位于一个目录下,如果不是的话,可以通过$: << "another dir"来追加模块检索路径。
14.nil对象存在to_s方法,.nil?可以判断对象是否为null,
nil和false是Ruby中的false值,0,""等都不是
15.string.upcase,string.downcase
16.rails中为所有类型加入了blank?方法
"".blank?
" ".blank?
[].blank?
{}.blank?
nil.blank?
都返回true
17./rubY/i =~ “hello ruby" 返回匹配的索引,不匹配返回nil
18.ARGV[0]代表第一个命令行参数,不包括程序名本身
19.读取文件,非常简单
file = open("/Users/**/vhost1.conf") puts file.read file.close或者一行一行读file = open("/Users/qiucheng/vhost1.conf") count = 0 while text = file.gets puts count.to_s + ":" + text count += 1 end file.close20. ==,equal?,eql?,===ruby的equal?和java的==一样,==和java的equals一样。eql?方法被定义和==行为一致,只是在有些类,如Fixnum中,他的行为被改写了1==1.0 //true1.eql?1.0 //false,===大多数时候和==一个意思,但是当它的左边是下面情况时,意思不同String === "string" //"string".instance_of? String(1..3) === 1 //true/aa/ == "23aa" //true21.instance_of?只能判断当前对象是否是某个类的对象,如要判断父类情况(即和java中得instanceof一致),需要用is_a?
22.定义类方法3种方式
class Tool #方式一 def Tool.hello puts "hello" end #方式二,定义在class<<Tool块中 class << Tool def bye puts "bye" end def hi puts "hi" end end #方式三,self def self.arigato puts "arigato" end end23.类中定义一个常量需要大写字母开头,并且通过Tool::Version来访问类变量需要使用@@开头,并且书写一个方法用于暴露该变量
24.异常
begin 1/0 rescue => error puts error puts error.backtraceensure puts "I am finally"end
a = Integer("") rescue 0 #前者解析抛异常,返回0Exception是异常类的子类(Java的Throwable),StandardError类似于java的Exception类,RuntimeError类也存在
25.打印数字的二进制形式
printf("%08b",15)
26.hash用法
hash.each,hash.each_key,hash.each_value
Hash.new("123") #当key不存在时,123为默认值
Hash.new{
#默认hash函数
|hash,key|
hash[key] = key.upcase
}
hash.has_key?,key?,member?,include?判断key是否存在
hash.delete(key) //删除一个键值对,返回value
#hash可以排序,排序结果是数组的数组(长度为2,由元素和值组成)
hash.sort{
|x,y|
x[1] <=> y[1] #根据value排序
}
27正则表达式
//是正则表达式的开始结束符,当正则表达式中要包含/时,需要转义,但是转义又很晦涩,
所以可以使用%r{123/}来达到和/123\/一样的效果/
正则表达式发明出来的时候是无法匹配多行的,所以对
/^.+$/无法匹配多行的字符串,
但是现在的话,Ruby将正则表达式分成一行一行
ab\ncdefg=>ab和cdefg两行
这样/^c.+g$/ =~ "ab\ncdefg"就能够匹配第二行并且返回匹配上的索引3.能够匹配所有元素(除了换行)为了让它匹配换行,可以使用//m模式Regexp.quote("a*b+")将为我们生成被转义后的正则表达式当我们需要括号但又不想在backreference时获得她的索引时,可以使用?:/(a.b)(?:[a-z]+)/m =~ "23a\nbdef" #开启换行模式,$1匹配a\b,def本来是$2的,但是?:取消了它的存在$`,$&,$'分别为匹配成功结果的左半部,本身和右半部除了普通的sub和gsub外,还支持这种subputs "ab213Efg".sub(/\d+/) { |matched| #在213两侧加尖括号 "<" + matched + ">" }scan方法可以枚举所有匹配上的值"ab213Efg456".scan(/\d+/) { |matched| puts matched }没有block时,scan将直接返回["213","456"]28.StringIO可以把字符串当做输入输出流require "stringio" stringio = StringIO.new stringio.print "hello\n" #写入string stringio.print "bye\n" stringio.rewind while line = stringio.gets puts ":" + line end29.读取文件时,可以使用这种方法取代 while file.get另外也可以通过file.each_byte,file.getc一个一个读取字节或者字符file.each { |line| print file.lineno, line, "\n" #lineno可以实时获得 }30.文件系统FileFile.openFile.basename(path),File.dirname,File.extnameFile.split("/usr/bin/local/a.txt") => ["/usr/bin/local","a.txt"]File.split("a.rb") => [".","a.rb"]File.split("/usr/bin/local") => ["/usr/bin","local"]和文件系统操作打交道时,可以使用fileutils库require "fileutils"FileUtils.copy/move/cp_r(递归copy),这里的_r实质上是cp -r同理还存在FileUtils.mkdir_p(path|path数组) => mkdir -pFileUtils.rm(文件名|文件名数组)FileUtils.compare(from,to)比较文件内容#Dir和文件夹相关处理Dir.pwd #当前路径Dir.chdir(path) #更换路径Dir.glob("**/*\0**/.*)返回所有当前文件夹下所有文件,其中\0用来区别两个pattern,第二个pattern中的点号代表隐藏文件Dir.mkdir/rmdir#FileTest类中有不少boolean方法FileTest.directory?/file?/exists? 判断是否存在,为文件或者目录FileTest.readable?/writable?/executable?FileTest.size返回文件大小31.Time.now返回当前时间,Time.now - 100返回100秒前DateTime.now也返回当前时间(DateTime类继承自Time类),但是他是以日为单位,所以加减法都是以日为单位DateTime.now.to_time可以转换到Time对象Time.now.utc返回0时区可以使用Time.now.year/month/day/hour/minute/sec等获得详细信息Time.now.to_i获得秒数,不是毫秒数31.定义一个类的<,<=,>,>=,=,between?方法的话,只需要定义该类的<=>,然后在类中include "Comparable"就可以了,因为该模块里定义了所有其他操作,他们都基于<=>如果一个类需要有迭代的功能,那么需要实现each方法,并且include Enumerator模块32.class Bdef testputs "in b"endendclass Cdef testputs "in c"end
endB.instance_method(:test)//可以获得一个解绑定的方法method=B.new.method(:test)//获得一个绑定在B对象上的方法method.unbind.bind(C.new)//将方法解绑定,再绑定到C的实例上method.call//打印in b33.instance_eval,class_eval通过这两个方法,可以对实例或者类动态的添加方法method_arr = ["foo", "bar"] a = Class.new #创造一个匿名类 obj = a.new #匿名类实例 obj.instance_eval {#为实例定义动态函数 method_arr.each { |method_name| define_singleton_method(method_name) { #为该对象定义动态方法 puts method_name } } } obj.foo obj.bar
=============
method_arr = ["foo", "bar"] a = Class.new #创造一个匿名类 obj = a.new #obj.foo调用将失败 a.class_eval {#为该类定义动态函数 method_arr.each { |method_name| define_method(method_name) { #为该对象定义动态方法 puts method_name } } } obj = a.new #此时调用这些方法将成功 obj.foo obj.bar#为类添加方法module ClassMethods def scope(name, body) #通过class_eval和define_method结合使用添加方法 ClassMethods.class_eval { define_method(name) { |*args| body.call(*args) } } end end class Test11 extend ClassMethods #给Test11添加aa方法,方法接受一个参数 scope :aa, lambda { |x| puts "hello" + x.to_s } end Test11.aa(123)