蜀绣简谱:阿当的博客
来源:百度文库 编辑:九乡新闻网 时间:2024/04/28 22:04:01
Array 类
1)新建数组。 ruby中新建数组有多种方法。
<1> 使用[],类似于js。
================================
a = [1,2,3]
p a #=> [1,2,3]
================================
<2> 使用Array.new。
================================
a = Array.new
p a #=> []
a = Array.new(5)
p a #=> [nil,nil,nil,nil,nil]
a = Array.new(5,0)
p a #=> [0,0,0,0,0]
================================
<3> 使用%w。%w方法很奇怪,后面接的可以直接是字符串,而不必带”号。通常情况下,可以选用()做为参数的边界符,如果字符串本身包含()这样的字符,为免造成影响,还可以使用<> || !! @@ AA这样的来做边界符。%w方法会以空格为分隔,将字符拆分成数组。
================================
a = %w(abc 123 def 456 ghi)
p a #=> ["abc","123","def","456","ghi"]
a = %w<(abc) 1(23 g()h>
p a #=> ["(abc)",“1(23”,"g()h"]
================================
<4>其它对象的to_a方法。 比如说hash对象就可以通过to_a转换成数组。
================================
h = {“name” => “adang”,”sex” => “male”}
a = h.to_a
p a #=>[["name","adang"],["sex","male"]]
================================
<5>字符串的split方法。
================================
s = “ab-123-cd-45″
a = s.split(“-”)
p a #=>["ab","123","cd","45"]
================================
2) 数组的索引。
<1> a[n]
这个用法和别的语言没啥区别,唯一奇怪的是n可以为负值,表示倒数。另外,a.slice(n)和a.at(n)效果和a[n]相同。
================================
a = ["a","b","c","d"]
p a[0] #=> a
p a[-2] #=> c
p a.slice(-2) #=> c
p a.at(-2) #=> c
================================
<2> a[n..m]
会将a[n]到a[m]之间的范围建立出新的数组返回。a.slice(n..m)和a[n..m]效果相同。
================================
a = ["a","b","c","d"]
p a[1..3] #=> ["b","c","d"]
p a[1..6] #=> ["b","c","d"]
p a.slice(1..3) #=> ["b","c","d"]
p a[a] #=> ["a","b","c","d"]
================================
<3> a[n,len]
从a[n]处开始获取len个元素,建立新数组并返回。a.slice(n,len)和a[n,len]效果相同。
================================
a = ["a","b","c","d"]
p a[1,2] #=>["b","c"]
p a[1,6] #=>["b","c","d"]
p a.slice(1,2) #=>["b","c"]
p a #=>["a","b","c","d"]
================================
<4> a.values_at(n1,n2,…)
a[n..m],a[n,len]方法新建的数组都只能是连续位置上元素,a.values_at方法可以返回不连续的索引组成的新数组。
================================
a = ["a","b","c","d"]
p a.values_at(1,3,0) #=> ["b","d","a"]
p a #=> ["a","b","c",“d”]
================================
3) 改写数组。a[n],a[n..m],a[n,len]不仅可以读数据,还能写数据。注a.at,at.slice方法都只能读,不能写,只有a[]可以写。
================================
a = ["a","b","c","d","e","f","g"]
a[1..3] = ["B","C","D"]
a[4,2] = [1,2]
p a #=> ["a","B","C","D",1,2,"g"]
================================
4) 插入元素。 ruby中插入数据原理和js里一样。js中是通过splice方法先删几个元素,再添几个元素,ruby中也是如此。
================================
a = ["a","b","c"]
a[2,0] = [1,2]
p a #=> ["a","b",1,2,"c"]
a = ["a","b",“c”]
a[1,1] = [1,2,3]
p a #=> ["a",1,2,3,"b","c"]
a = ["a","b","c"]
a[1..2] = [1,2,3]
p a #=> ["a",1,2,3]
================================
5) 交集、并集和差集。 ruby中数组还可以进行交集和并集的计算,分别使用 & 和 | 作为运算符。
================================
a = ["a","b","c","d"]
b = ["b","e","a"]
p a & b #=> ["a","b"]
p a | b #=> ["a","b","c",“d”,"e"]
p a #=> ["a","b","c","d"]
================================
对数组直接使用 + – 运算符,可以分别得到数组连接的效果和差集的效果。
================================
a = ["a","b","c","d"]
b = ["b","e","a"]
p a – b #=> ["c","d"] (a有,但b没有的元素)
p a + b #=> ["a","b","c","d","b","e","a"] (a和b简单地叠加)
p a | b #=> ["a","b","c","d","e"] (a和b的并集,重复元素去除)
================================
6)数组的队列性。 和js一样,ruby中的数据也有push,pop,unshift,shift方法,此外a << 赞同于a.push。
================================
a = ["a","b","c"]
a.unshift(1)
a << 2
a.push(3)
p a #=> [1,"a","b","c",2,3]
p a.shift #=> 1
p a #=> [“a”,"b","c",2,3]
p a.pop #=> 3
p a #=> ["a","b","c",2]
================================
7) a.concat和 + 。 在js中数组是不能直接相加的,如果需要组合两个数组,是用a.concat(b)来实现的,但js中a.concat(b)是会返回一个新数组的,还可以利用这一点轻松复制一个复杂类型的数组。但ruby中concat是具有破坏性的,会影响到a。如果想不影响到a,可以使用+号。
================================
a = ["a","b","c"]
b = [1,2,3]
c = a + b
p c #=>["a","b","c",1,2,3]
p a #=>["a","b","c"]
c = a.concat(b)
p c #=>["a","b","c",1,2,3]
p a #=>["a","b","c",1,2,3]
================================
8)a.compact。 a.compact可以从数组中删除nil元素。有compcat和compact!之分。
================================
a = [nil,"a",nil,"b","c",nil]
a.compact!
p a #=> ["a","b","c"]
================================
9)a.uniq。 a.uniq可以删除数组中的重复元素。有a.uniq和a.uniq!之分。
================================
a = [1,2,3,4,3,2,1]
a.uniq!
p a #=> [1,2,3,4]
================================
10) a.delete(x)、a.delete_at(n)、a.delete_if{|item| …}
a.delete(x)可以直接从数组中删除指定元素(为啥js中没有这么好用的方法?T_T )。
a.delete_at(n)删除指定索引的元素(js的splice方法去死吧 T_T)。
a.delete_if{|item| …} 遍历数组元素,如果区块返回结果为真,则删除。 (for循环去死吧 T_T)。
================================
a = [1,2,3,2,4,nil]
a.delete(2)
p a #=> [1,3,4,nil]
a = [1,2,3,2,4,nil]
a.delete_at(2)
p a #=> [1,2,2,4,nil]
a = [1,2,3,2,4,nil]
a.delete_if{|item| item > 2 if item}
p a #=> [1,2,2,nil]
================================
11) a.slice!()。 前面说过a.slice的效果等同于a[],包括a.slice(n),a.slice(n..m),a.slice(n,len)。slice方法还有slice!的形式,slice!方法的返回值相同,但会从数组中删除掉返回值。
================================
a = [1,2,3,4,5,6]
p a.slice!(1) #=> 2
p a #=> [1,3,4,5,6]
p a.slice!(2..3) #=> [4,5]
p a #=> [1,3,6]
p a.slice!(1,1) #=> [3]
p a #=> [1,6]
================================
12) a.collect和a.map。如果需要让数组中所有元素统一变化,再也不用for()去循环,再赋值这么麻烦了,a.collect和a.map都可以返回让数组中的值进行处理之后,将返回的结果组成新数组。a.collect和a.map效果相同,且都有!的形式。
================================
a = [1,2,3]
a.collect!{|item| item * 2}
p a #=> [2,4,6]
a.map!{|item| item * 3}
p a #=> [6,12,18]
================================
13) a.fill。a.fill可以将数组a的元素改写为指定的参数。但我a[n..m]=和a[n,len]=不同的是,a.fill只能将指定范围内的元素修改成一种参数(只有一种)。a.fill有a.fill(value),a.fill(value,begin),a.fill(value,begin,end),a.fill(value,n..m)几种不同的方式。
================================
a = [1,2,3,4,5,6]
a.fill(8)
p a #=> [8,8,8,8,8,8]
a = [1,2,3,4,5,6]
a.fill(8,3)
p a #=> [1,2,3,8,8,8]
a = [1,2,3,4,5,6]
a.fill(8,3,2)
p a #=> [1,2,3,8,8,6]
a = [1,2,3,4,5,6]
a.fill(8,2..4)
p a #=> [1,2,8,8,8,6]
================================
14)a.flatten。 将数组扁平化,多层数组可以变成一个单层的数组。有a.flatten和a.flatten!之分.
================================
a = [1,[2,3],[[4,5],6,[7,[8,9]]]]
a.flatten!
p a #=> [1,2,3,4,5,6,7,8,9]
================================
15)a.reverse。 逆转数组,有a.reverse和a.reverse!之分。
================================
a = [1,2,3]
a.reverse!
p a #=> [3,2,1]
================================
16)sort和sort_by。 sort对数组排序,对应的还有sort!方法。另外ruby还提供sort_by方法,sort_by返回新数组,没有对应的sort_by!
=================================
a = [2,4,3,5,1]
a.sort!
p a #=> [1,2,3,4,5]
b = a.sort_by{|i| -i}
p b #=> [5,4,3,2,1]
p a #=> [1,2,3,4,5]
=================================
17) each和each_width_index。 数组遍历最常用的做法是使用each方法,但each方法只会返回一个返回值,只有元素,没有索引,如果需要索引的话,可以使用each_with_index方法。
=================================
a = [1,2,3]
a.each{|i| print i,”\n”}
a.each_with_index{|i,n| print n,” : “,i,”\n”}
=================================
阿当 @ 9:39 上午 [filed under ruby on rails]No Comments »{十一月 27, 2009} ruby学习笔记(4)
Numeric类
1) 整型和整型相加结果为整形,整形和浮点型相加,结果为浮点型。
================================
p 1+1 #=>2
p 1+1.0 #=>2.0
p 3 * 2.0 #=>6.0
================================
2) divmod。 除了+ – * / %之外,ruby中数值类型还有divmod方法,它也是除的运算符,只是返回值是数组的形式,第一项是商,第二项是余数。
================================
p 16.divmod(5) #=> [3,1]
================================
3) Math模块和round方法。ruby提供了Math模块,但和一般语言不同的是,round、ceil和floor方法并不是从属于Math模块的,而是直接绑定在数值类上的。Math模块提供的方法有sin、cos、tan、asin、acos、atan、exp、log、log10和sqrt。数值类型的对象转换可以用to_f、to_i方法。浮点型转整型会直接去掉小数点后的值。字符串调to_i方法相当于js中的parseInt方法。
================================
f = 4
p Math.sqrt(f) #=> 2
include Math
p sqrt(f) #=> 2
p 10.to_f #=> 10.0
p 10.8.to_i #=> 10
p “123″.to_i #=> 123
p “123abc”.to_i #=> 123
p “abc123″.to_i #=> 0 (不是nil哦)
p 1.2.round #=> 1
p 1.2.floor #=> 1
p 1.2.ceil #=> 2
================================
3) 循环。 数值类型可以直接用来循环。
================================
ary = []
3.times{|i| ary << i}
p ary #=>[0,1,2]
ary = []
2.upto(5){|i| ary << i}
p ary #=>[2,3,4,5]
ary = []
5.downto(2){|i| ary << i}
p ary #=>[5,4,3,2]
ary = []
10.step(20,3){|i| ary << i}
p ary #=>[10,13,16,19]
10.step(2,-3){|i| ary << i}
p ary #=>[10,7,4]
================================
阿当 @ 9:38 上午 [filed under ruby on rails]No Comments »{十一月 23, 2009} ruby学习笔记(3)
1) sleep方法。 ruby中也有定时器,sleep相当于js中的setTimeout函数,不同的是sleep后的参数单位是秒,不是微秒。
2)ruby的函数中return是可以省略的,如果省略,方法中的最后一个语句的计算值会是返回值。
========================================
def area(x,y,z)
xy = x * y
yz = y * z
zx = z * x
(xy + yz +zx) * 2
end
p area(2,3,4) #=>52
========================================
3) 判断对象的类型。ruby有个和js中判断对象类型相近的方法,instance_of?。除了instance_of?之外,ruby的对象还有个很好用的方法,叫class,通过class方法可以直接得到对象的类型,需要注意的是.class返回的不是字符串,而是类。
========================================
str = “abc”
arr = [1,2,3]
p str.class #=> String
p arr.class #=> Array
p str.instance_of?(String) #=> true
p arr.instance_of?(Array) #=> true
p str.class == String #=> true
========================================
和js一样,ruby中所有的类都继承自Object。但和js不一样的是,js的instanceof可以一直往上追踪,但ruby不行,ruby为往上追踪提供了另外一个方法is_a?。例如
=========================================
js:
var arr = [1,2,3];
alert(arr instanceof Array); //true
alert(arr instanceof Object); //true
ruby:
arr = [1,2,3]
p arr.instance_of?(Array) #=> true
p arr.instance_of?(Object) #=> false
p arr.is_a?(Object) #=> true
==========================================
4) ruby中的常量真是容易定义,用大写字母开头的就是常量了。常量在修改值的时候会报警告。
5)类名。和js不一样的是,js中是出于习惯,提倡类名首字母大写,并没有做硬性要求。ruby的类名却强制性要求首字母大写。原因是ruby要求类名必须为常量。
6)构造函数。ruby的构造函数并不是和类名同名的方法,而是统一使用initialize方法。一般语言都可以设定构造函数的访问性,设计模式中的单独模式就是通过构造函数的访问性做的文章。as3中强制构造函数为public,而ruby强制构造函数为private。
7) 实例化。 ruby的实例化一个类,不是通过new 类名()这种通用方式,而是通过类名.new()。奇怪的ruby语法@_@。
8) 属性的访问性。和java一样,ruby并不支持直接访问类中的属性,如果要访问类中的属性,需要先通过attr_reader:属性名(只读),attr_writer:属性名(只写),attr_accessor:属性名(读写)来设定属性的访问权限。ruby中没有var关键字,不能通过函数产生变量的作用域。在js里,我们可以在类中定义一个私有变量,在所有的方法中调用。私有变量只要定义为和方法在同一级别,那么它就可以在各个方法中负责通信。ruby中不能使用这种方法,ruby在类里没办法定义变量,只能在方法中定义变量。方法和方法之间如果想通信只能通过@变量,也就是实例变量进行通信。@变量就像是js中的this.xxx变量一样,但js中的this.xxx只能是public的,可读可写,ruby通过attr_xxxx可以控制@变量的访问性。
9)方法的访问性。方法的访问性是通过public,private和protected进行限制的。和一般语言将访问性关键字放在方法前面不同的是,ruby的访问性是通过public:方法名1,方法名2。。。这样的方式进行声明的。属性的访问性可以放在前面,但方法的访问性要放在方法之后,如果放在方法前面会出现方法未定义的报错。除了初始化方法恒化private,其它方法缺省为public。
10)类方法(静态方法)。 ruby中定义类方法有三种方法。
=========================================
1)
class HelloWorld
def HelloWorld.hello(name)
print name,” said Hello.”
end
end
HelloWorld.hello(“John”)
2)
class HelloWorld
..
end
class << HelloWorld
def hello(name)
print name,” said Hello.”
end
end
HelloWorld.hello(“John”)
3)
class HelloWorld
def self.hello(name)
print name,” said Hello.”
end
end
HelloWorld.hello(“John”)
=========================================
需要注意的是,类方法不能访问实例变量。
11)类变量(静态变量)。ruby中类变量是通过加@@标识的。
12)类常量。类中还可以定义常量,还是要求大写字母开头。类中不能定义和方法平缓的变量,但是可以定义和方法平级的常量,常量可以被所有方法调用。类常量的调用方法是类名::常量名。
13)继承。 ruby中的继承不是使用extend关键字,它更简洁,使用<就可以了。ruby也只支持单继承。
14) 类的示例。
========================================
class Dog
attr_accessor:name
def initialize(name = “wang cai”)
@name = name
end
def call
print “I’m a dog , my name is “, @name ,”\n”,Version,”\n”
end
def self.move(num=0)
print “Dog had moved “,num,” bu\n”
print Version,”\n”
end
Version = “1.0″
public :call
end
a = Dog.new
a.name = “huan huan”
a.call
Dog.move(5)
class BigDog < Dog
def call
print “I’m a big dog , my name is “, @name,”\n”
end
end
b = BigDog.new(“abc”);
b.call
print Dog::Version
========================================
15)模块。模块是ruby特有的功能之一。模块和类很像,但和类最大的不同在于模块不能实例化,也不能继承。模块的作用有两个,一个是用于提供命名空间。第二提供Mix-in功能。Mix-in和继承很像,但它不是继承,在《javascript设计模式》一书里,将Min-in称为掺元继承,YUI提供的augment方法,思路就是Mix-in。模块是通过include关键字读入的,它和as中的with()方法有相似的地方,include了文件之后,前辍就可以不用写了。
16)模块的常量和类常用调用方法一样。模块名::常量名。模块的方法调用和类的方法调用不同,可以使用模块::方法名,也可以使用模块.方法名。
17)模块定义的方法默认是不对外部公开的,(模块内没有public private protect关键字),要将方法对模块外部公开,必须使用module_function。
===================================
module HelloModule
Version = “1.0″
def hello(name)
print “Hello, “,name,”.\n”
end
module_function : hello
end
p HelloModule::Version #=>”1.0″
HelloModule::hello(“Alice”) #=> hello, Alice.
include HelloModule
p Version #=>”1.0″
hello(“Alice”) #=>Hello, Alice
===================================
阿当 @ 4:10 下午 [filed under ruby on rails]No Comments »{十一月 22, 2009} 标签内联事件和event对象
event对象在IE和firefox下表现是不同的。在IE下,event是window对象的一个属性,是在全局作用域下的,而在firefox里,event对象是做为事件的参数存在的:
===========================
document.getElementById(“btn”).onclick = function(){
alert(arguments.length);
};
===========================
这代代码在IE下弹出0,而在firefox下弹出1。在firefox下这个参数就是event对象了。
如果在标签内联事件中触发事件会如何呢?
===========================
function handler(){
alert(arguments.length);
};
===========================
在IE和firefox下,这段代码弹出的都是0.也就是说,标签内联事件并没有被替换成
===========================
btn.onclick = handler;
function handler(){
alert(arguments.length);
}
===========================
而是替换成了
===========================
btn.onclick = function(){
handler();
}
function handler(){
alert(arguments.length);
}
===========================
在标签内联事件中,我们使用arguments[0]可以在firefox下访问到event对象。
===========================
===========================
因为不使用标签内联事件的话,我们可以给处理函数传参,从而指定arguments[0]的变量名,通常情况下,我们平时也的确是这么处理的:
===========================
document.getElementById(“btn”).onclick = function(e){
e = window.event || e; //e兼容IE和firefox,指向event对象
};
===========================
在标签内联事件中我们没办法指定参数名,是不是就没办法直接写个变量在IE和firefox下兼容地指event对象呢?不是的,可以用“event”这个变量名兼容地指向event对象,注意,只能是“event”,如果是“a”,“b”,“Event”之类的全都不行。可能是因为考虑到标签内联事件中无法指定参数变量名,所以故意留个了“event”这个关键字吧。
===========================
===========================
这段代码在IE和firefox下都可以正常地弹出“click”。
有趣的是,标签内联事件中我们甚至可以写注释,可以使用字符串:
===========================
//只弹出1
//弹出1和3
//弹出“string”
===========================
如果我们既用标签内联事件绑定了事件,又用DomNode.onxxxx绑定了事件,又会如何呢?
===========================
document.getElementById(“btn”).onclick = function(){
alert(456);
};
===========================
会如何呢?会弹出456,不弹出123。相当于
===========================
document.getElementById(“btn”).onclick = function(){
alert(123);
};
document.getElementById(“btn”).onclick = function(){
alert(456);
};
===========================
后面的处理函数把前面的处理函数覆盖掉了。如果我们给DomNode是通过attachEvent和addEventListener来绑定事件的呢?
===========================
function handler(){
alert(456);
}
if(document.all){
btn.attachEvent(“onclick”,handler);
} else {
btn.addEventListener(“click”,handler,false);
}
===========================
很顺利地,先弹出了123,后又弹出了456。
阿当 @ 11:37 下午 [filed under js]2 Comments »{十一月 22, 2009} 关于prototype
protype是个很有趣的属性,它是“类”所持有的属性。在javascript里原生提供的一些内置类,其本质也是“类”,内置类提供的方法我们也可以通过prototype来覆盖掉,这是件很有趣的事情。例如:
=========================================
var str = str2 = “ab,cd,ef,g”;
var arr = str.split(“,”);
String.prototype.split = function(a){
return “hello,you input: ” + a;
}
String.prototype.length = 200;
var arr2 = str2.split(“,”);
alert(str.length);
alert(arr);
alert(arr2);
Array.prototype.toString = function(){
return “12345″;
}
alert(arr);
=========================================
猜猜看,会依次弹出什么?“10”,“ab,cd,ef,g”,“hello,you input:,”,“12345”。呵呵,看来属性没办法覆盖,第一个没弹出“200”,但方法可以覆盖,不论是String类的split方法,还是Array类的toString方法,都被我们覆盖掉了。
当然,覆盖内置类提供的方法这种操作绝大部分时候都是不好的,通常情况下,我们更多的是为内置类提供更多的方法,让程序更好用,例如:
==========================================
var arr = ["a","b","c"];
var str = arr.join(“-”);
alert(str);
Array.prototype.join2 = function(a){
return this.join(“^^^”+a+”^^^”);
}
str = arr.join2(“-”);
alert(str);
==========================================
我们给内置类添加一个join2方法,让它在join数组的时候,能做更多我们自定义的事。因为修改的是内置类的原型,所以js中所有的原生数据都直接获得了新的方法,这是种很方便的功能。但这样的方法其实并不推荐,它会对原生内置类的原型造成“污染”,可能会出现奇怪的问题,特别是多人合作的时候,或者引入第三方js库的时候,出现一些奇怪的bug,查都不好查。我们更推荐的方法是定义一个新的类,然后把所有需要扩展的功能放到这个新的类里去,通过这个新的类来完成功能,而不是直接修改原型。如:
===========================================
var arr = ["a","b","c"];
var str = arr.join(“-”);
alert(str);
arrayManager = {
join : function(oarr,ostr){
return oarr.join(“^^^”+ostr+”^^^”);
}
}
str = arrayManager.join(arr,”-”);
alert(str);
===========================================
prototype是什么意思呢?它表示“原型”,简单地说,js中的类是分两级来实现的,一级是“原型级”,它比较底层,另一级是“实例级”,实例级的优先级比原型级高,如果new一个类,调用方法的时候,先优先在实例级去查找有无这个方法,如果没有,才会去原型中找。实例级在分配内存时会为每个实例分配一个,而原型级只会在内存中分配一个,通过传址的形式传给每个类的实例。所以为了节约内存,我们更推荐写类的时候将方法通过prototype的方式写出来,而不要写在function里,例如:
=========================================
//不推荐的写法
function Dog(){
this.name = “WangCai”;
this.call = function(){
alert(”wang wang”);
}
}
//推荐的写法
function Dog(){
this.name = “WangCai”;
}
Dog.prototype = {
call : function(){
alert(“wang wang”);
}
}
=========================================
正因为prototype是通过传址的方式供各实例调用的,所以如果对prototype进行了修改,无需重新再new一遍,实例的方法就已经更改了:
=========================================
function Dog(name){
this.name = name;
}
Dog.prototype.call = function(){
alert(“I’m “+this.name);
}
var myDog = new Dog(“WangCai”);
myDog.call();
Dog.prototype.call = function(){
alert(“wang wang wang wang wang”);
}
myDog.call();
function Cat(name){
this.name = name;
this.call = function(){
alert(“I’m “+this.name);
}
}
var myCat = new Cat(“Mimi”);
myCat.call();
Cat.prototype.call = function(){
alert(“miao miao miao miao miao”);
}
myCat.call();
=========================================
myDog第一次call的时候,弹的是I’m WangCai,第二次就是wang wang wang wang wang了 ;myCat两次都弹的是I’m Mimi。
正是因为prototype的这种特性,所以open api的系统里,因为会支持第三方开发,为了防止第三方恶意覆盖掉javascript内置类的方法,都会封装一套接口给第三方使用,以阻止它们访问原生内置类的原型。
阿当 @ 8:53 上午 [filed under js]No Comments »{十一月 22, 2009} ruby学习笔记(2)
1)ruby的语句可以换行。这一点和js不同,js中换行视作一行语句结束,相当于在句尾加了“;”号,如果一条语句换行写,会报错。ruby中语句可以换行,而且为了提高可读性,bury鼓励不使用“;”号,希望一行语句只写在一行里,可以的话,不要在同一行里写多条语句。
2)ruby中if,while等语句都不带{}号,相反,一些方法例如each则会带{},习惯了C系的语法,看着还真不习惯。总之因为不带{},所以在写if等语句时,一定要注意缩进,不然程序没法看了。
3)ruby中空格不能随便乱加,如果要加空格让程序好看一点,一定要注意讲求平衡。例如:
==============================
a+b
a + b 的效果相同
a +b 效果却等同于 a(+b),a()方法传入+b作为参数
==============================
4) to_i 方法。字符串转换成数字类型。相当于js中的parseInt()。
5) 布尔型转换。在ruby中,布尔型也是为true和false,同其它语言一样,其它类型的值也能和布尔型进行隐式转换。但和大多数语言不同的是,在ruby中,false和nil以外所有的对象都为真,false和nil为假。包括0,在ruby中其实都是相当于真,这点和一般的语言不大一样。另外,ruby是个支持谓语的语言,鼓励返回布尔型数据的方法命名时加上“?”,这么做也是为了提高可读性。例如 isNumber? isGood?
6) 条件判断。 在ruby中,条件判断有一点很奇怪的是else if的写法,既不是“else if”也不是“elseif”,是“elsif”,汗,为啥把那个e给省掉了?看着多别扭啊。。。
============================
a = ARGV[0]
b = ARGV[1]
if a > b then
print “a > b”
elsif a == b then
print “a = b”
else
print “a < b"
end
============================
除了if,ruby中还提供了unless方法,语法和if一样,但和if正相反的是,unless中的条件不成立时,才会执行。
7) case语句。 ruby 中的case语句相当于其它语言中常用的switch,但ruby中的格式奇怪一点,功能也更强一点:
=============================
=begin
这是一般的用法
=end
tags = ["A","IMG","PRE"]
tags.each{ | tagname |
case tagname
when "P","A","I","B" then #bury这里可以写多个参数,用逗号隔开
print tagname,"has child.\n"
when "IMG","BR" then
print tagname,"has no child.\n"
else
print tagname,"cannot be used.\n"
end
}
=begin
when 里还可以放 String,Numberic之类的类型名,判断类型
=end
array = ["aa",1,nil]
item = array[0]
case item
when String
puts "item is a String."
when Numberic
puts "item is a Numeric."
else
puts "item is a something."
end
=begin
when 里还可以放正则表达式
=end
case line
when /^From:/i
print "找到寄件人了。\n"
when /^To:/i
print "找到收件人了。\n"
else
print "啥也没找到。"
end
=============================
需要注意的是,ruby中的when后面的条件不会自动转换类型,比如说1和"1"是不一样的。另外,很重要的一点是,when后面的语句不需要加break,这和C系的switch是不一样的。
8) ===。ruby中也有===号,但它和js中的===并不相同,ruby中的===左边可以是数字、字符串,也可以是正则,还可以是类型。
=============================
p (2 === 2) #=> true
p /zz/ === “zyzzy” #=> 2
p String === “xyzzy” #=>true
=============================
阿当 @ 8:52 上午 [filed under ruby on rails]No Comments »{十一月 20, 2009} ruby学习笔记(1)
1) ruby的函数在调用的时候可以加括号,也可以不加括号。
函数定义的格式也比较奇怪:
==============================
def hello
print(“Hello World”)
end
hello()
==============================
2)ruby的输出方法有print,puts,p和pp。其中print是普通输出,它接受多个参数,在输出的时候会把所有参数拼起来然后输出;puts和print类似,不同的地方在于puts会在输出之后自动加上换行,如果传了多个参数,那个每个参数后都会自动加上换行;p和pp设计的目的都是为给程序员调试用的,它们输出的信息能包含更多信息,例如字符串在输出的时候会加上引号,pp和p不同的地方在于pp输出时会自动加入缩进和换行,让数据显示时的可读性更好。
3)单引号和双引号。和php一样,单引号中不能包含变量,双引号中可以包含变量。在ruby中,单引号中的\n这样表示换行之类的转义字符都会无效,直接输出出来。
4)注释。 ruby中的注释和c系语言不同,不是使用//和/**/,取而代之的是#和=begin,=end。
=============================
=begin
我是一个多行注释哦,
我换行了,
我又换行了
=end
# 我是一个单行注释
=============================
5) if判断。 也和C系不同,看起来更像是vb的语法。没有{}这样明显的分隔,如果不加上缩进的话,可读性该有多差啊@_@
=============================
if a >= 10 then
print(“big”)
else
print(“small”)
end
==============================
6) 循环。使用while:
==============================
i = 1
while i <= 10
print(i,"\n")
i = i + 1
end
==============================
使用times方法。当循环次数确定时,使用times方法会更简单:
==============================
100.times {|i|
print "hello ",i,"\n"
}
100.times do |i|
print "hello",i,"\n"
end
==============================
使用for。ruby的for有两种用法,一种是类似于C系的for(var i=0;i
==============================
sum = 0
for i in 2..5
sum += i
end
print sum
==============================
另一种类似于js的for(var p in Obj){}:
==============================
names = ["a","b","c"]
for name in names
print name,"\n"
end
==============================
和js的for (p in obj)不同的是,这里的p不是索引。例如上面代码的输出不是0,1,2,而是"a","b","c"。
如果换成是hash,又会怎么样呢?
==============================
names = {"a" => 1,”b” => 2,”c” => 3}
for name in names
print name,”\n”
end
==============================
输出是什么呢?a1,b2,c3,直接将键和值拼起来一块儿输出了。
ruby 的退出循环也比较奇怪。break和C系一样,C系的continue在ruby中叫next。注意,exit是退出整个程序,不是退出循环。
7) 迭代。 其实迭代也是我们熟悉的循环中的一种。和C第语言不同的是,对于复杂数据类型,比如数组,我们使用的不是for(var i=0,n=arr.leng;i
===============================
#数组
name = ["a","b","c"]
name.each{| n |
print n,"\n"
}
#hash
a = {"name" => “adang” , “sex” => “male”}
a.each{| key , value |
print key , ” : ” , value , “\n”
}
===============================
hash。 ruby也支持hash数据。和js不同的是,js的hash格式是{name1 : value1 , name2 :value2},而ruby的hash格式不是用:分隔,而是=>,这种使用习惯更像php。在调用hash数据时,js可以通过hash[name],或者hash.name的方式调用,而ruby只能通过hash[name]调用。
==============================
a = {“name” => “adang”,”sex” => “male”}
print a["name"]
==============================
9) 数组。 ruby的数组和js没太大区别,也可以通过 a = [] 来快速定义一个数组,有点奇怪的是ruby中数组长度不是通过arr.length来获得的,而是通过arr.size,这里size不是属性而是方法。
10) 正则。和js一样,ruby的正则也可以通过/abc/的形式创建,但它的匹配方法和js不同,js中最常用的匹配方法是test,/abc/.test(str)是最常用的方式。在ruby中,匹配是通过 =~运算符来实现的,如果匹配成功,返回索引值,如果匹配失败,返回空值nil。nil应该相当于js中的null了:
==============================
p /Ruby/ =~ “Ruby” #=> 0
p /Ruby/ =~ “Diamond” #=> nil
==============================
11) ARGV数组。 这个数组是用来保存命令行对指令脚本传入的实参,类似于js中的augments数组。
12)读取文件。 读取文件的方式和php有点像,也是先打开文件,然后读取内容,最后关闭文件。
==============================
#整篇读取
filename = ARGV[0]
file = open(filename)
text = file.read
print text
file.close
#结合正则表达式,逐行读取 (我怎么看着这么像读取数据库中的数据的形式呢?)
pattern = Regexp.new(ARGV[0])
filename = ARGV[1]
file = open(filename)
while text = file.gets do
if pattern =~ text
print text
end
end
file.close
==============================
13) 将输出保存到文件中。 ruby比起js可以做更多的事了,比如说,读取或输出文本到文件,在ruby中将输出结果存在文件里非常简单,执行程序的时候,在指令的后面加上 “>文件名”,则输出就会被存在文件里。
==============================
> ruby test.rb > test.html
==============================
14) require。 像大多数语言一样(js除外),ruby支持require,需要被require的文件只需要被 require “fileName“就可以被包含进来了,值得注意的是,fileName可以省掉”.rb”后辍。
15) 全局变量和局部变量。js的全局变量和局部变量是通过var关键字结合函数作用域实现的,在ruby中,是通过$符号来区别全局变量和局部变量的。比如说a.rb和b.rb同时都定义了$str和str两个变量,a.rb里require了b.rb文件,那么b.rb中的$str会影响到a.rb文件,因为他们是同一个变量,而b.rb中的str不会影响到a.rb中的str。
16)==,eql和equal。在ruby中所有的对象都持有身份标识(ID),它是ruby原生支持的。这让我想起YUI了,YUI中也会自动对对象生成ID作为身份标识,不仅是DOM对象,也包括程序中的对象,这点和ruby异曲同工,只是ruby原生就支持,通过object_id可以获得。
==============================
ary1 = []
p ary1.object_id #=> 67653636
==============================
判断两个给定的对象是不是同一对象(ID相同),可以通过equal?方法来进行判断。
==============================
str1 = “foo”
str2 = str1
str3 = “f” + ”o“ + “o”
p str1.equal?(str2) #=> true
p str1.equal?(str3) #=> false
==============================
在这里有个概念需要清楚,在ruby中,一切数据都是对象,”foo”在这里是作为一个对象存在的,这点和as3一样,str2 =str1这一步的时候,其实不是复制了一份”foo”字符传给了str2,而是直接将str1的址传给了str2,此时str1和str2指向的是同一个内存地址,这么设计的目的当然是为了节约内存。equal?()比较的应该是内存地址是否一致,而不是“值”是否一致。在js中,传值还是传址,是根据数据类型决定的,赋值时无法指定,string,num等等基本类型是传值,array,hash等复杂类型是传址。php里传值还是传址是通过有无&符号决定的,有&传址,无&传值。ruby里只会传址,不会传值。但和as3一样,虽然是传址,但其实它不是普通的传址,而是传的一种“不变对象”,当“不变对象”的值被改动的时,其实并不是改变“不变对象”本身,而是新生成一个不变对象,而将旧的不变对象由垃圾回收机制自动回收。关于这一点,可以参考黑羽的《action script3殿堂之路》第21页“基元数据类型的深入讨论”。
前面说的是“址”的比较,对于“值”的比较,ruby提供了==和eql方法,==和eql之间的关系就相当于js中的==和===关系。
==============================
p 1.0 == 1 #=> true
p 1.0 eql?1 #=> false
==============================
阿当 @ 12:03 下午 [filed under ruby on rails]No Comments »{十一月 19, 2009} [原创] 如何在ietester下使用firebug
首先,需要说明的是,此firebug并不是firefox下的插件firebug。众所周知,firebug是firefox下的调试利器,但在ie下没有相关的插件,为了在ie下实现firebug功能,所以出了这么一个组件,它是完全用js生成的仿firebug界面。功能当然没有真正的firebug强大,但其操作和firebug很像,界面也像,对于习惯firebug的工程师来说,使用它非常亲切。其官方网站是http://uicss.cn/r.php?hr=http://getfirebug.com/lite.html
有一点很让人郁闷的是,官方提供的加载它的方法是给html加载一个