zoukankan      html  css  js  c++  java
  • ruby抽取url

    http://www.cxyclub.cn/n/5652/

    Ruby | Block和迭代器

    2007-04-16 15:40:43

    标签:Ruby ROR Rails 敏捷开发 yield

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://blackanger.blog.51cto.com/140924/23876

           Block是只在花括号或do … end之间的一组代码,和方法调用相关联。为什么有两分解符号,书上有两种解释,一种是说因为使用习惯,有人用花括号,有人用do…end。另一种原因是因为用花括号比do…end绑定更紧。书上推荐:单行用花括号,多行用do…end

    看下面例子:

    def fun

    yield

    end

    fun { puts “hello baby” }

    这会输出 hello baby

    如果没有加yield的话,不会出错,返回nil。但是你用了yield没有给它接收块的时候就会出现异常(no block givenLocalJumpError))。看javaeye里有人讨论yield到底是什么东西,感觉有点可笑。搞那么复杂干什么。想知道yield怎么实现,看源码不就行了吗,我们现在知道yield能做什么就行了!只要出现了yield,必须给它块来喂它。就像个宠物似的。哈哈。

    可以给yield提供参数,比如

    def call_back

    yield(“hello”,99)

    end

    call_back {|str,num| puts str,num}

    do |str,num|

    puts str,num

    end

    就会输出:

    Hello

    99

    竖线之间给出参数名来接受来自yield的参数。这个感觉很别扭呀!

    我们可以修改一下:

    def call_back(*a)

    a.each do |arg|

    puts arg

    end

    end

    call_back([“hello”,99])

    说明下:each方法中通过使用yield来实现迭代处理。

    上面的each语句还可以写成:

    a.each {|arg| puts arg}

    a.each{|arg|;puts arg;}

    这两句都可以,但是个人认为加分号不好,破坏了Ruby的纯净性。

    块的出现使函数非常容易被封装和传递。事务处理可以被完美的封装到一个函数体内部:

    拿文件处理来说,我们可以使用块来改写open方法。。。把异常处理封装进去。

    还记得刚才说的那个LoaclJumpError异常吗?我们可以利用这种异常来产生不同的处理文件的方式。如下面伪代码:

    Class File

    ….

    def self.open(filename,openflag=”r”)

    begin

    f=File.new(filename,openflag)

    yield f

    f.close if f

    rescue

    return f

    ensure

    #f.close

    #一些消除操作等

    end

    这样我们就有了两种不同的open的使用方式:

    1) 以块打开文件。这个是正常的方式:

    File.open(‘test’) do |f|

    Puts f.read

    end|

    2) 普通打开方式,我觉得这倒不正常了,处理方式不正常,不是用户不正常

    f = File.open(“test”) #后面并没有传入块,会引发异常

    txt = f.read()

    puts txt

    f.close

    不过在javajavascript里也有这么应用的。但是javajs里异常处理是必须的。没有像Ruby里这么使用的,不加块参数故意引发异常来用另一种形式来表现方法。比较灵活!

    但是异常总归是异常!,有可能带来安全性问题!我们在异常处理的地方又加入了另一种处理方式。如果我们能在block传入之前就能判断block的值的话,这样避免异常的产生比较合理吧!

    我们可以用Proc迭代器:

    来改写下上面的文件处理伪代码:

    class File

    def self.open(filename,openflag=”r”,&block)

    f = File.new(filename,openflag)

    if block

    block.call f

    f.close if f

    else

    return f

    end

    end

    end

    还可以用不同的两种方式来表现方法。

    上例中的&block是标准的写法(当然你也可以写成&black,hehe ),这样才会产生一个名为block的Proc对象,然后你可以用call来执行块了:)

    打开Rubyfxri工具,输入call来查看帮助。找到Proc#call,会看到关于call方法的介绍(解析块的)。

    prc.call(params,...) => obj

    prc[params,...] => obj

    例子:

    a_proc = Proc.new {|a, *b| b.collect {|i| i*a }}

    a_proc.call(9, 1, 2, 3) #=> [9, 18, 27]

    a_proc[9, 1, 2, 3] #=> [9, 18, 27]

    a_proc = Proc.new {|a,b| a}

    a_proc.call(1,2,3)

  • 相关阅读:
    数据库流行度9月排行榜:Oracle 的老骥伏枥和 MongoDB 逆风飞扬
    ssh 执行单引号和双引号问题
    【Netapp】在模拟器中使用disk removeowner报错
    ES6的let和const命令(一)
    ES6的let和const命令(一)
    ES6的let和const命令(一)
    ES6的let和const命令(一)
    Android开发之《异常处理》
    Android开发之《异常处理》
    Android开发之《异常处理》
  • 原文地址:https://www.cnblogs.com/lexus/p/1935201.html
Copyright © 2011-2022 走看看