ruby小记

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的module
1.用作工具方法管理库
module SakopModule
  def ok
    puts "ok " + self.to_s
  end
  module_function :ok #必须这么暴露,不然外头访问不到

  PI = 3.14

end

2.可以解决多继承,假设一把剑它既属于武器有可能属于宝藏,由于ruby不支持多继承,所以暂且让Sword类继承自Weapon,然后再宝藏模块中定义如下方法
module Treasure 
  def price
    return @price * "999999999"
  end
end
然后再Sword中包含他
class Sword < Weapon
   attr_accessor :price
   @price = 10
   include Treasure
end
这样就可以调用定义在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.close
20. ==,equal?,eql?,===
ruby的equal?和java的==一样,==和java的equals一样。
eql?方法被定义和==行为一致,只是在有些类,如Fixnum中,他的行为被改写了
1==1.0 //true
1.eql?1.0 //false,
===大多数时候和==一个意思,但是当它的左边是下面情况时,意思不同
String === "string" //"string".instance_of? String
(1..3) === 1 //true
/aa/ == "23aa" //true

21.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

end
23.类中定义一个常量需要大写字母开头,并且通过Tool::Version来访问
类变量需要使用@@开头,并且书写一个方法用于暴露该变量

24.异常
begin
  1/0
rescue => error
  puts error
  puts error.backtrace
ensure
  puts "I am finally"
end

a = Integer("") rescue 0 #前者解析抛异常,返回0
Exception是异常类的子类(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外,还支持这种sub
puts "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
end

29.读取文件时,可以使用这种方法取代 while file.get
file.each {
    |line|
  print file.lineno, line, "\n" #lineno可以实时获得
}
另外也可以通过file.each_byte,file.getc一个一个读取字节或者字符
30.文件系统
File
File.open
File.basename(path),File.dirname,File.extname
File.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 -p
FileUtils.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 B
   def test
      puts "in b"
   end
end
class C
def test
      puts "in c"
   end  
end
B.instance_method(:test)//可以获得一个解绑定的方法
method=B.new.method(:test)//获得一个绑定在B对象上的方法
method.unbind.bind(C.new)//将方法解绑定,再绑定到C的实例上
method.call//打印in b
33.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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值