Ruby语言学习
ruby的定位: programer's best friend
它是一门面向程序员的语言,语法很灵活,功能很强大。 相比与严谨的java来说,ruby可谓敏捷的多了
ruby是自顶向下执行的。哪怕是在类里面,也是一行接着一行执行代码的。要深入理解ruby的函数面,因为用好块(block)和闭包(closure)极大的提高了代码的简洁和可读
rails : ruby 的 web框架。 基于 coc 的原则 和 ruby的动态语言特性可以很便捷的开发web应用。 类似于我们的webx框架
gem : 有时候也叫做rubygems , 是ruby下的包管理器 。 类似于 maven
ruby有它自己的虚拟机,会做ruby的内存管理,垃圾回收。 类似于java的jvm 。
Rvm: ruby version manager 是一个让多版本ruby环境共存的一套解决方案。
Jruby 100% 纯ruby实现的运行在java虚拟机下的语言,是结合ruby和java的桥梁
irb : 交互式的ruby运行环境,做写小测试,学习非常不错
ri : ruby的doc文档工具,非常强大
搭建ruby开发环境:
http://www.ruby-lang.org/en/downloads/
简单的介绍下我的环境搭建过程:
由于我用的是ubuntu操作系统,所以参照
http://lanvige.iteye.com/blog/851836 安装了rvm,中间虽然有几个问题但是稍微下资料也都顺利解决了。Ri , irb ,gem等都没有问题。可是问题出在如果用netbeans进行debug的话,无法进行fast debug,有相应的依赖没有解决掉。网上查了些资料也没给出个解决方法。
无奈之下就只有放弃rvm直接进行ruby环境安装了。超级简单,按如下:
http://ryanbigg.com/2010/12/ubuntu-ruby-rvm-rails-and-you
下载了个安装脚本,作者把所以该解决的依赖都解决了。所有问题都不在了。。。
ide用过radrails和netbeans , 感觉还是netbeans要好一点。
我的一些实践,近距离感觉一下ruby
1如何打印一句hello world
java: 定义一个类,再定义一个main方法,然后编译,然后再运行
ruby:
wuzhong@TAOBAOWDS46:~$ ruby -e "p 'hello'"
"hello"
ruby 类似于 java命令,指向的是他们的运行环境, -e 标识后面跟着一个ruby脚本 p 'hello';
p 就是print方法,内置在ruby core中,所以可以直接拿来用。
字符串可以用“ 也可以用 ' ,但是有区别的:
请看这个例子
a='hello'
puts "#{a}"
puts '#{a}'
输出的结果是:
hellohello echo
hello
#{a}
2ruby的类型结构
在ruby中,一切皆是对象。。这个比java更加要明确一点,毕竟java夹杂着原子类。
irb(main):012:0> /abc/.class
=> Regexp
irb(main):013:0> (1..9).class
=> Range
irb(main):002:0> 1.class
=> Fixnum
irb(main):003:0> "a".class
=> String
irb(main):004:0> nil.class
=> NilClass
irb(main):005:0> 111111111111111111111111111111111111111111111.class
=> Bignum
irb(main):006:0> 0.1.class
=> Float
irb(main):007:0> [1,2].class
=> Array
irb(main):013:0> {"a"=>1,"b"=>2}.class
=> Hash
irb(main):014:0>
irb(main):015:0* Hash.new.class
=> Hash
irb(main):016:0> true.class
=> TrueClass
irb(main):017:0> false.class
=> FalseClass
3. 看一下 block的威力,大幅缩减代码量
irb(main):025:0> (1..10).each{|i| p i}
1
2
3
4
5
6
7
8
9
10
=> 1..10
irb(main):030:0> (1..10).each do |i|
irb(main):031:1* p i
irb(main):032:1> end
输出同样的结果
了解一下过程: 首先 1..10 这个返回的是一个Range。我们可以通过 (1..10).class来验证。
接下来我们需要迭代这个数组: ri Range 我们发现有个each方法。。ri Array.each参照doc文档就很简洁的写出上面的代码来了。 注意代码块 可以用 { } 也可以用 do end
wuzhong@TAOBAOWDS46:~/workspace/ruby/block$ more repeat.rb
def repeat(n)
if block_given?
n.times { yield }
else
raise ArgumentError.new("I can't repeat a block you don't give me!")
end
end
repeat(4) { puts "Hello." }
p "=========================="
repeat(4)
wuzhong@TAOBAOWDS46:~/workspace/ruby/block$ ruby repeat.rb
Hello.
Hello.
Hello.
Hello.
"=========================="
repeat.rb:5:in `repeat': I can't repeat a block you don't give me! (ArgumentError)
from repeat.rb:11:in `<main>'
4.ruby 的语法糖,便于扩展。
Ruby 是一个相当灵活的语言,她允许用户去改变她本身。 Ruby 的核心部分可以被更改或重新定义,模块可以被添加。Ruby 试着不去妨碍程序员。
比如(+) 是用做加法的运算符。如果你更喜欢使用易读的 plus 的话,你可以给 Ruby 的内建 Numeric 类添加一个函数。
class Numeric
def plus(x)
self.+(x)
end
end
y = 5.plus 6
# y is now equal to 11
同样的元编程也是基于这个原理,定义或者覆盖原来的方法
5.ruby 继承
class Child < Father
end
mixin
于其他面向对象语言不同,Ruby “有意”只提供单继承。不过 Ruby 拥有模块(在 Objective-C 里面叫做类别)。模块是把许多方法放在了一个类别里。
类可以混合一个模块,得到这个模块提供的所有方法。比如所有提供 each 方法的类可以混合 Enumerable 模块,来得到这个模块提供的所有方法,当然这些方法都会调用 each 做循环。
class MyArray
include Enumerable
end
一般来说,Ruby 爱好者相对于复杂和限制颇多的多态继承方法来讲更偏向于这种混合方法。
这篇文章介绍的比较通俗易懂了
http://thinkinginruby.iteye.com/blog/148967
6. ruby的封装性
局部变量 以小写字母或下划线卡头 var _var
全局变量 以$开头 $var
类变量 类中定义,以@@开头 @@var
实例变量 对象中定义,以@开头 @var
常量 以大写字母开头 Var
#定义了一个全局变量
$pub_var = "public var"
class Person
#定义了一个类变量,类比于java的static
@@name2 = $pub_var
#实例变量 attr_accessor会自动生成get 和set方法
attr_accessor :name
def initialize
#定义的局部变量
age =12
@name = "test"
p age
# @@name2 = "person"
# name = "test123"
end
#定义一个类方法
def self.name2
@@name2
end
private
def test
p "test"
end
public
def test2
p "test2"
end
end
ps = Person.new
p ps.name
p ps.age
#p ps.name2
p Person.name2
7. ruby 来处理xml
应用场景主要是maven的pom文件,当前清空工程里有很多依赖库,但是都是乱序排列的
目标: 通过该脚本对dependencies中的元素进行排序
# To change this template, choose Tools | Templates
# and open the template in the editor.
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
require 'rexml/document'
include REXML
class PomFormater
def initialize(file_name)
Dir.chdir("lib")
raise Exception.new(file_name + " dosn't exist") unless File.file?(file_name)
@doc = Document.new(File.new(file_name))
end
def sort
dependencys = XPath.first(@doc, "*/dependencyManagement/dependencies")
#p dependencys.size
parent = dependencys.parent
#p parent
elements = Element.new("dependencies")
parent.delete_element(dependencys)
parent.add_element(elements)
arr = Array.new
taobao_arr = Array.new
ali_arr = Array.new
dependencys.each_element do |element|
group_name = element.elements["groupId"].text.downcase
if group_name =~ /com.taobao/
taobao_arr << element
elsif group_name =~ /com.alibaba/
ali_arr << element
else
arr << element
end
end
arr = arr.sort_by{|x| x.elements["groupId"].text.downcase }
taobao_arr = taobao_arr.sort_by{|x| x.elements["groupId"].text.downcase }
ali_arr = ali_arr.sort_by{|x| x.elements["groupId"].text.downcase }
taobao_arr.concat(ali_arr).concat(arr)
taobao_arr.each { |e| elements.add_element(e) }
end
def out_put
s = ''
@doc.write(s)
open("tmp.xml","w"){|f| f << s }
p "please format it in your ide"
end
end
测试代码
$:.unshift File.join(File.dirname(__FILE__),'..','lib')
require 'test/unit'
require 'pom_formater'
class Demo
def foo
p "this is demo.foo method"
end
end
class PomFormaterTest < Test::Unit::TestCase
def test_foo
pf = PomFormater.new("pom_1.xml")
pf.sort
pf.out_put
end
def test_demo
Demo.new.foo
end
end
8. jruby的应用
the best of jvm . 是不是best暂且不予评论
jruby能充分使用ruby的动态性和语法的简洁性,同时可以使用丰富的java企业级类库。 最终要的是可以直接集成到现有的javaee应用中去.
知识我们需要安装jruby的运行环境,和jdk差不多,分别设置jruby_home 和 path 就OK了,使用起来也很方便。。
require 'java' //jruby 需要申明这个,其余都一样了
include_class 'com.taobao.wuzhong.spring.Hello'
class JrubyHello //千万不要用"< Hello"来实现接口,否则和java集成会报错
def hello
p "this is jruby"
end
end
和java集成:
@Test
public void test() throws ScriptException {
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine engine = m.getEngineByName("jruby");
engine.getContext().setAttribute("a", new Integer(11), ScriptContext.ENGINE_SCOPE);
engine.eval("puts 2 + $a");
}
另外如果使用spring的话,框架已经支持jruby和groovy了
<lang:jruby id="jhello"
script-interfaces="com.taobao.wuzhong.spring.Hello"
refresh-check-delay="1000"
script-source="classpath:com/taobao/wuzhong/spring/JrubyHello.rb">
</lang:jruby>
补充资料:
ruby和java的异同
http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/to-ruby-from-java/
http://onestepback.org/articles/10things/
http://blog.csdn.net/zl728/archive/2010/08/14/5812901.aspx
很好quickstart
http://www.ruby-lang.org/en/documentation/quickstart/
闭包问题:
http://www.ibm.com/developerworks/cn/java/j-cb01097.html
http://www.blogjava.net/ponzmd/archive/2007/09/19/146552.html