庄周梦蝶

生活、程序、未来
   :: 首页 ::  ::  :: 聚合  :: 管理

1、异常的相等性,如果两个异常的class、message和backtrace一样,那么认为这两个异常是相等的,可以通过==判断。
def method
    
raise 'foobar'
end

errors 
= []
2.times do
    Thread.new do
      begin
        method
      rescue 
=> e
        errors 
<< e
      end
    end.join
end
puts errors[
-2== errors[-1]    #=> true (1.9)   false(1.8)

2、SystemStackError现在继承Exception类,而非原来的StandardError:
1.8 
 
SystemStackError < StandardError  # => true
1.9
  
SystemStackError < StandardError # => nil
   SystemStackError < Exception      #=> true

3、移除了Exception#to_str方法
begin
   
raise "foo"
rescue
   $!.to_str
end

#=> undefind method "to_str" for #<RuntimeError:foo>


posted @ 2008-10-03 13:26 dennis 阅读(544) | 评论 (0)编辑 收藏

1、Proc加了新方法Proc#yield,这只是Proc#call的别名方法,是为了能让Proc也可以像block那样传入方法并且调用yield。
a_proc = Proc.new {|a,b| a+b}
a_proc.
yield(1,2# => 3

def test(&block)
  block.
yield(1,2,3)
end
test do 
|a,b|
   a
+b   # => 3
end
test 
&a_proc # =>3

2、没有参数的block的基数(参数个数,arity):
1.8
  
lambda{}.arity  #=> -1
1.9
  
lambda{}.arity #=> 0
所谓arity就是方法调用无法忽略的参数个数。这跟Erlang,Prolog中的arity的概念并无二致。

3、proc关键字现在是Proc.new的同义词,proc在1.8的时候跟lambda关键字是同义词,也就是proc定义的是一个lambda而非字面

意义上的Proc,1.9改过来了。
1.9:

proc{
|a,b|}.arity        # => 2
proc{|a,b|}.call(1)        # => nil
Proc.new{|a,b|}.arity        # => 2
Proc.new{|a,b|}.call(1)        # = nil

1.8:
proc{|a,b|}.arity        # => 2
proc{|a,b|}.call(1)        # => ERROR: (eval):1: wrong number of arguments (1 for 2)
Proc.new{|a,b|}.arity        # => 2
Proc.new{|a,b|}.call(1)        # => nil

1.8时候第二个调用出错的原因在于lambda在调用参数过多过少的时候都将报error,这是lambda跟Proc的一个区别之一。

4、Proc#lambda? 用来判断某个Proc是否具有lambda语义或者block语义:
lambda{}.lambda?  #=>true
proc{}.lambda# =>false
Proc.new{}.lambda# =>false



posted @ 2008-10-02 13:54 dennis 阅读(681) | 评论 (0)编辑 收藏

三、类和模块
1、Module#instance_methods, #private_instance_methods, #public_instance_methods Module这三个方法都将返回方法名

的symbol组成的数组,而非过去的字符串数组。

2、Module#const_defined?, #const_get 这两个方法都添加一个参数flag,用来决定是否将它的ancestor中的const包括在查
找链中,例如:
module A; X = 1def foo; end end
module B
  include A
  const_defined? 
"X"                              # => true
  const_defined? "X",false                        #uninitialized constant
  const_get "X"                                   # => 1
  const_get "X",false                             #uninitialized constant  
end

3、Module#class_variable_defined?方法:
class X; end
X.class_variable_defined? :@@a                    
# => false
class X; @@a = 1 end
X.class_variable_defined? :@@a                     
# => true
class_variable_{get,set}方法:

class B; self end.class_variable_set(:@@a, "foo")        # => "foo"

4、Module#attr等价于Module#attr_reader:
class Test
  attr:foo
  
def initialize
    @foo
=3
  end
end
t
=Test.new
puts t.foo   
#=>3
t.foo=4     #undefined method "foo="

5、接下来是一个bug fix的问题。下面这段代码是为了证明对象的singleton类继承自对象的类:
class X;end; x=X.new; class << x;p self < X; end

在1.8上,这段代码打印nil,这是不符合Ruby的对象模型的,因此在1.9运行已经可以打印正确结果true了。
如果不理解这点,参照俺过去写的《Ruby对象模型》

6、新增Module#module_exec方法,与Object#instance_exec类似

7、绑定未绑定的方法时进行额外的子类型检查,例如下面的代码:
class Foo; def foo; end end
module Bar
   define_method(:foo, Foo.instance_method(:foo))
end
a
=""
a.extend Bar
a.foo

在1.8上,这段代码只有当执行到a.foo的时候才报错:"foo":bind arguments must be an instance of Foo(TypeError)
因为foo是Foo的instance method,因此调用者必须是Foo或者其子类的instance。 而在1.9中,在绑定还没有绑定的方法的时候引入了额
外的检查,因此上面这段代码不必等到a.foo调用就将报错:
class Foo; def foo; end end
module Bar
   define_method(:foo, Foo.instance_method(:foo))   
#=》 in "defined_method":bind arguments  must be a subclass

of Foo
<TypeError>
end

8、binding#eval方法,新增加的:
a=1
binding.eval(
"p a")  => 1

这个貌似与1.8中的:
a=1
eval(
"a",binding)

没有什么不同。

posted @ 2008-10-01 13:52 dennis 阅读(644) | 评论 (0)编辑 收藏

二、Kernel 和 Object
1、引入了BasicObject对象,作为一个顶级的空白状态对象:
BasicObject.instance_methods # => [:==,:equal?,:"!",:"!=",:__send__]
Object.ancestors       # => [Object, Kernel, BasicObject]

引入这个对象对于Ruby对象体系带来的影响我还不清楚。
2、instance_exec方法,允许传递参数、self到一个block并执行之,也就是说为特定的instance执行block。
def magic(obj)
   
def obj.foo(&block)
     instance_exec(self, a, b, 
&block)
   end
end
= Struct.new(:a,:b).new(1,2)
magic(o)
puts o.foo{
|myself,x,y| puts myself.inspect;x + y }

更多例子:
= Struct.new(:val).new(1)
o.instance_exec(
1){|arg| val + arg }  =>2


在Ruby 1.8中实现这个方法:
class Object
  module InstanceExecHelper; end
  include InstanceExecHelper
  
def instance_exec(*args, &block) # !> method redefined; discarding old instance_exec
    mname = "__instance_exec_#{Thread.current.object_id.abs}_#{object_id.abs}"
    InstanceExecHelper.module_eval{ define_method(mname, 
&block) }
    begin
      ret 
= send(mname, *args)
    ensure
      InstanceExecHelper.module_eval{ undef_method(mname) } rescue nil
    end
    ret
  end
end

3、Kernel的require方法载入的文件将以完整路径存储在变量$"中,等价于:
$" << File.expand_path(loaded_file)

通过在irb中观察$"变量即可看出差别。

4、Object#tap方法,将对象传入block并返回自身,用于链式调用:
"hello".tap{|a| a.reverse!}[0] #=> "o"
"F".tap{|x| x.upcase!}[0]  #=> "F" (注意到"F".upcase!返回的是nil)

5、Kernel#instance_variable_defined?方法:
= "foo"
a.instance_variable_defined? :@a                  
# => false
a.instance_variable_set(:@a, 1)
a.instance_variable_defined? :@a                  
# => true

6、Object#=~

匹配失败的时候返回nil而不是false
1 =~ 1 # => nil

7、Kernel#define_singleton_method 方法,
= ""
a.define_singleton_method(:foo){
|x| x + 1}
a.send(:foo,
2)  =>3
a.foo(
2)  => 3

8、Kernel#singleton_methods, Kernel#methods,返回的是将是方法名symbol组成的数组,过去是方法名的字符串数组。


posted @ 2008-10-01 13:48 dennis 阅读(589) | 评论 (0)编辑 收藏


一、新的语法和语义
1、新的Hash定义语法:
例如{a:2}  等价于 {:a=>2}
但是 {"a":2} 出错,并不等价于 {:"a"=>2}

2、试验性质的block内的局部变量
在1.8,block的与外部同名的变量是同一个变量,也就是说block内的变量也可以修改外部的同名变量,这很容易形成难以查找的bug。
例子:
# {常规参数;局部变量}
= 2
= lambda{|;d| d = 1}
a.call()
d        
# => 2

注意到,分号后的d是block局部变量。

3、block的参数现在都是局部变量

4、新lambda语法,试验性质:
->a,b {a+b}.call(1,2)   => 3

一些比较诡异的写法:
-> { }.call # => nil
-> a, b  { a + b }.call(1,2# => 3
= 1-> a, b; c  { c = a + b }.call(1,2); c # => 1(注意这里,;号的c是block的局部变量,因此c=1在lambda调用前后没有改变。)

5、 .()的调用方式
过去
lambda{|*d| d}.call(1,2,3)

现在可以简化为
lambda{|*d| d}.(1,2,3)

.()这样的方式都将调用接受者的call方法,无论接收者是什么,例如:
 "foo".(1,2)   # ~>  undefined method `call' for "foo":String (NoMethodError)

显然,这个方式另一种形式上的method_missing,比如在类中应用:

class Test
  
def self.call(*d)
     d
   end
end
Test.(
1,2,3)  => [1,2,3]
这个特性也是试验性质

6、block可以使用&block做参数咯。
例子:
class Test
   define_method :foo 
lambda{|&b| b.call("hello")}
end
t
=Test.new
t.foo do 
|b|
   puts b    
=> hello
end

7、新的block参数语义,|v| 现在等价于 |v,|
还是通过例子吧:
1.8:
def m; yield 12; end
m{
|v| v}                                          # => [1, 2]
                                                  # !> multiple values for a block parameter (2 for 1)
1.9:
def m; yield 12; end
m{
|v| v}                                          # => 1

8、允许数组多重展开
def foo(*a)
     a
end
foo(
1*[2,3], 4*[5,6])                        # => [1, 2, 3, 4, 5, 6]

= [1,2,3]
= [4,5,6]
[
*a, *b]                                         # => [1, 2, 3, 4, 5, 6]

9、可选参数后允许再有强制参数的存在,这在过去是不允许的。例如下面的代码在1.8是错误的,而1.9却可以正常运行:
def foo(a,b="test",c)
  puts c
end
foo(
1)   => wrong number of arguments(1 for 2)
foo(
1,2=> 2
foo(
1,3=> 3
foo(
1,2,3)  =>3
更复杂的:
def m(a, b=nil, *c, d)
     [a,b,c,d]
end
m(
1)  =>error
m(
1,2)  => [1,nil,[],2]
m(
1,2,3=>[1,2,[],3]
m(
1,2,3,4)  =>[1,2,[3],4]
m(
1,2,3,4,5)   => [1,2,[3,4],5]
m(
1,2,3,4,5,6]  =>[1,2,[3,4,5],6]

10、?c的语义,过去?+字符返回字符的ascii码整数,现在返回字符"c"
例如:
?a  => 97  (1.8)
?a  
=> "a" (1.9)

11、[]方法的参数现在可以将数组和hash联合使用,例如下面的例子:
class Test
   
def [](*a)
     puts a.inspect
   end
end
a
=[1,2,3]
Test.new[
*a,:a=>2]   =>  SyntaxERROR:compire error (1.8)
Test.new[
*a,:a=>2=>  [1,2,3,{:a=>2}] (1.9)


12、打印字符,打印字符和负数,
1.8
  printf 
"%c","a"  => can't convert String into Integer
  printf "%u",-1   => ..4294967295

1.9:
  printf 
"%c","a"  => a
  printf 
"%u",-1   => -1
13、defined?方法和local variable:

RUBY_VERSION                                      
# => "1.8.5"
RUBY_RELEASE_DATE                                 # => "2006-08-25"
= 0
defined? a                                        
# => "local-variable"
1.times do |i|
  defined? i                                      
# => "local-variable(in-block)"
end

VS.

RUBY_VERSION                                      
# => "1.9.0"
RUBY_RELEASE_DATE                                 # => "2007-08-03"
= 0
defined? a                                        
# => "local-variable"
1.times do |i|
  defined? i                                      
# => "local-variable"
end

posted @ 2008-10-01 13:37 dennis 阅读(759) | 评论 (0)编辑 收藏

    与锋爷、小朱、阿宝中午打的直奔会场,上了酒店五层,发T-shirt,要求换上。立马在卫生间上演一处猛男秀。来的人不少,我们都坐到后排去鸟,一开始在放某个关于opensource的video,鸟语听力很差再加上隔的远字幕都看不清,只好到处看看等待开始。2点半正式开始,先是Peter cheng做个open source camp的介绍,然后是品高的架构师分享了他们电信增殖业务一个项目的架构——用ActiveMQ构建的异步消息队列。Peter cheng再次现身介绍了objectweb(有无拼错)社区,什么四方国件中法联合,不是很清楚,有点昏昏欲睡(当天凌晨3点睡的觉,毋怪)。
   接下来是此次活动的正题,大伙提交想要分享的topic,然后分成几个时间点和房间开讲。由活动参与者来提供topic这样的形式挺新奇,遗憾的是大多数人并没有准备,最后还是仅有9个topic(有无记错?),3个关于python的,一个老外讲敏捷(?),一位香港的开发者的经验分享(听不懂广东话),两个关于集群的topic,还有个MM(后来知道是广发银行的)关于开源与商业的topic,一个javascript的科普topic(貌似是关于jquery)。遗憾的是没有关于Ruby的topic。topic不多,就不用啥投票了,休息片刻,灌了两瓶矿泉水,大伙如鸟兽散到各个会议室,正题开始。
    我跟阿宝先去听了CPUG社区的大妈关于金山内部python训练营的培训经验的topic,该训练营叫蟒营,传说中的大妈穿了件“人生苦短,我用python”的哲思T-shirt,其实我一直想设计个T-shirt,上面印上一行字“Ruby恒久远,一颗永流传”。这个蟒营采用的是魔鬼高压训练法,将学生仔训练成职业开发者,加上大妈煽动,听着还是蛮有意思。俺比较疑惑的类似这样的高压训练法尽管能快速地挑选出合适的人,但是完全让学生去自学、放任自流的方法似乎也会浪费不少有潜质的学生,毕竟再好的苗子也需要锄草。大妈演讲另一个关键字就是靠谱,专业是很容易装出来的,一堆大词加上一表人才是很容易zhuangbility,而能实际干活出东西是才是kaopubility。时间不多,互动比较少,匆匆听完,赶去听Peter cheng的关于高可用性集群的topic。内容没多少新意,主要介绍的是在负载均衡、企业应用集群、数据库集群上开源领域相对于商业的替代解决方案:LVS、Terracotta、上面提到的objectweb社区的uns/controller(有无记错?)。一直在强调的一点是解决方案的透明性,如何不侵入地透明地解决企业应用的集群问题。
    听完这个后,大概5点多了,阿宝赶着去参加同学婚宴,俺也昏昏欲睡了,也就跟着阿宝一起撤退了,比较遗憾没有去听那个关于python组件的topic。第一次参加此类活动,尽管见到了传说中的司令等人,但是俺这个从来没有名片的倒不好意思去认识下,以后有机会再说了。



posted @ 2008-09-21 08:58 dennis 阅读(2027) | 评论 (6)编辑 收藏

看看甘肃日报消息

本报兰州9月13日讯(记者牛彦君)记者今天从省质量月活动现场了解到,我省质监系统在全省全面展开了乳制品专项监督检查,并对与三鹿集团有合作关系的酒泉市好牛乳业食品有限公司的产品全部封存,乳粉生产线已于9月10日查封,工作组也已于9月12日到达该企业。

“三鹿奶粉事件”发生后,省质监局立即启动应急预案积极应对,迅速组成了应急工作领导小组展开调查。9月9日,从住院患者处、定西市安定区、 岷县、漳县和兰州市永登县紧急抽取了部分样品,由甘肃省产品质量监督检验中心进行检验,现已在由石家庄三鹿股份有限公司生产的“三鹿慧幼”1至3段的5个 批次的该产品中检出了严禁在食品和饲料中添加的有毒物质———三聚氰胺,2段乳粉最高值达2563毫克/100克。同时,钙、钾、脂肪、钙磷比、亚硝酸盐等指标也不符合标准要求。为了保证检验的准确性,同时将4个样品送国家食品质检中心进行检验,检验结果一致。我省质监系统已于9月11日开始对该产品实施查封。

看看昨天抽查结果:
检出三聚氰胺婴幼儿配方乳粉企业名单序号 标称的企业和产品名称 抽样数 不合格数 三聚氰胺最高含量mg/kg

1、石家庄三鹿集团股份有限公司生产的三鹿牌婴幼儿配方乳粉 11 11 2563.00

两种单位:mg/100g和mg/kg,尽管都是2563

哦耶,将造假进行到底。

posted @ 2008-09-17 09:46 dennis 阅读(669) | 评论 (1)编辑 收藏

    最近各地出现很多婴儿胆结石的病例,并且这些患病婴儿吃的是同一品牌的奶粉,本来还遮遮掩掩说什么某品牌,早有人捅出来说是三鹿啊,还抵赖个啥啊。三鹿现在自己也承认了:
     新华网北京9月11日电(记者周婷玉)石家庄三鹿集团股份有限公司11日晚发布产品召回声明,称经公司自检发现2008年8月6日前出厂的部分批次三鹿婴幼儿奶粉受到三聚氰胺的污染,市场上大约有700吨。

  为对消费者负责,三鹿集团公司决定立即对2008年8月6日以前生产的三鹿婴幼儿奶粉全部召回。

  卫生部专家指出,三聚氰胺是一种化工原料,可导致人体泌尿系统产生结石。


    问题是真的是被污染的吗?请google、baidu 三聚氰胺和蛋白两个关键词。看看结果如何!原来三聚氰胺是奸商们用来提高产品蛋白含量以蒙混过关的化工原料。说要支持国货,如此作为的著名国货让人怎么支持。




posted @ 2008-09-11 23:55 dennis 阅读(1971) | 评论 (6)编辑 收藏


主要是比较offer跟poll两个方法的性能,开N个线程,每个线程往队列里写或者取500个整数。

线程数
20
50
100
200
500 1000
LinkedBlockingQueue     
15,0
31,15
32,16
63,32
203,47
563,110
ArrayBlockingQueue 15,0
16,15
31,15
47,16
125,47
364,68
PriorityBlockingQueue 78,78
172,188
360,422
813,969
3094,2641
6547,5453

逗号前的数字是offer测试花费的时间,逗号后的数字是poll测试花费的时间,单位毫秒。
结论:
1、ArrayBlockingQueue性能优于LinkedBlockingQueue,但是LinkedBlockingQueue是无界的。
2、ArrayBlockingQueue和LinkedBlockingQueue的poll方法总是比offer方法快,并发越高,差距越大
3、ArrayBlockingQueue和LinkedBlockingQueue的性能远高于PriorityBlockingQueue,显然优先队列在比较优先级上的操作上耗费太多
4、PriorityBlockingQueue的offer方法与poll方法的性能差距很小,基本维持在近似1:1

posted @ 2008-09-08 10:05 dennis 阅读(5842) | 评论 (5)编辑 收藏

    任何应用都需要与资源打交道,这个资源可能是文件、内存、网络、数据库、web服务等。特别是系统的可伸缩性和性能上,一个系统的可伸缩性很大程度上取决于该系统资源管理的可伸缩性。资源的获取是资源生命周期的起点,因此在此阶段的优化和配置对系统性能、可用性、稳定性、可伸缩性的影响是至关重要的。资源的获取要解决 这么两个问题:怎么找到资源,何时获取资源。
    资源的超找可以通过lookup模式,所谓lookup模式就是引入一个查找服务作为中介,让资源使用者可以 找到并使用资源提供者提供的资源。这方面一个显然的例子就是JNDI,我们通过JNDI查找EJB、数据库连接池等,另一个例子就是RMI,客户端通过命名服务查找到远程对象。查找服务提供查询语言,也提供接口让服务注册到它的容器内。
    何时获取资源?根据时机的不同可以分为预先获取模式和延迟获取模式。如果对系统的可用性和运行时性能要求比较高,那么可能你会预先加载或者分配所要用到的资源,通过一个资源提供者的代理对象拦截对资源的请求,返回预先加载或者分配的资源,从而提高系统性能。这方面的例子就是 memcached,memcached启动时预先分配内存来提高性能(相应的带来的是内存的不能有效利用)。线程池、数据库连接池也是预先获取模式的例子,通过预先创建的线程或者数据库连接,来提高系统的整体性能。反之,延迟获取模式就是尽可能到使用资源的最后一刻才去获取资源,一开始返回的只是一个资源的代理对象,真正使用到资源的时候由这个代理对象去加载实际的资源。延迟获取模式的例子也很多,例如 Hibernate的延迟加载,延迟加载的对象其实是一个代理类(通过java动态代理或者cglib增强),只有真正用到的时候才去数据库获取实际的数 据。函数式编程中的延时求值也是延迟获取模式的例子,没有求值前只是个promise,求值到的时候才force执行。Singleton模式下的单例也常常做延迟初始化,这是延迟获取模式的特化。
    如果资源的大小很大、极大或者是未知尺寸,预先获取会导致系统速度的缓慢甚至耗尽系统资源,延迟获取在获取的时候也可能时间过长难以忍受或者耗尽系统资源,两者都不适合,解决办法就是分步获取,这就是所谓部分获取模式。将资源的获取分为两步或者多步,每一步获取一定数目的资源,每一步获取资源也可以采用预先或者延迟的策略。这样的例子如socket读数据到缓冲区,一次可能只读一部分数据到缓冲区,分步才读完。再比如web页面一棵树的展 现,一开始可能只是显示部分节点,在需要查看一些节点的时候才会通过ajax加载和展开它们的子结点乃至深层子结点。

参考:POSA3 第二章

posted @ 2008-09-07 22:10 dennis 阅读(2461) | 评论 (1)编辑 收藏

仅列出标题
共56页: First 上一页 22 23 24 25 26 27 28 29 30 下一页 Last