zoukankan      html  css  js  c++  java
  • ruby send respond_to

    http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html

    http://galeki.is-programmer.com/posts/183.html

    1.3.2 send Important

    send( ) is an instance method of the Object class. The first argument to send( ) is the message that you're sending to the object - that is, the name of a method. You can use a string or a symbol, but symbols are preferred. Any remaining arguments are simply passed on to the method.

    class Rubyist
      def welcome(*args)
        "Welcome " + args.join(' ')
      end
    end
    obj = Rubyist.new
    puts(obj.send(:welcome, "famous", "Rubyists"))   # => Welcome famous Rubyists
    

    With send( ), the name of the method that you want to call becomes just a regular argument. You can wait literally until the very last moment to decide which method to call, while the code is running.

    class Rubyist
    end
    
    rubyist = Rubyist.new
    if rubyist.respond_to?(:also_railist)
      puts rubyist.send(:also_railist)
    else
      puts "No such information available"
    end
    

    In the code above, if the rubyist object knows what to do with :also_railist, you hand the rubyist the message and let it do its thing.

    You can call any method with send( ), including private methods.

    class Rubyist
      private
      def say_hello(name)
        "#{name} rocks!!"
      end
    end
    obj = Rubyist.new
    puts obj.send( :say_hello, 'Matz')
    

    Note:

    1. Unlike send()public_send() calls public methods only.
    2. Similar to send(), we also have an instance method __send()__ of the BasicObject class.

    如同其他的OO语言一样,在ruby中,通过给对象发送消息,来完成对象的功能,比如 str.upcase ,就是给str发送upcase的消息,点操作符(.),就是用来给对象发送消息的,str接受到消息,然后执行与消息对应的功能。

    但是,某些时候,我们并不知道对象能响应哪些消息,比如下面的代码就会产生错误: 

    1. > obj = Object.new
    2. > obj.talk
    3.  
    4. undefined method 'talk' for #<Object:0x12345678> (NoMethodError)

    因为obj对象没法响应talk这个消息,如果使用 respond_to? 这个方法,就可以实现判断对象能否响应给定的消息了:

    1. obj = Object.new
    2. if obj.respond_to?("talk")
    3.    obj.talk
    4. else
    5.    puts "Sorry, object can't talk!"
    6. end

    这样即使obj不能响应talk,也不会使代码产生错误退出,我们也可以应用 respond_to? 方法,根据对象的属性,在程序运行时灵活的控制。

    与 respond_to? 相对应,send 方法和点操作符一样,用来给对象发送消息,比如文章开始的 str.upcase ,用 send 可以写成 str.send("upcase"),它们实现的功能是完全相同的,那么为什么还要用send呢?

    这是因为,send 发送的消息,在程序运行时是可变的,我们可以根据不同的输入,动态的向对象发送不同的消息。

    比如一个图书管理系统,每本书都有诸如作者、出版社、日期、价钱这些,我们要根据用户的输入查询某本书的属性,如果不用send,我们要对程序的输入做一个一个的测试:

    1. print "Search for: "
    2. request = gets.chomp
    3.  
    4. if request == "writer"
    5.   puts book.writer
    6. elsif request == "press"
    7.   puts book.press
    8. elseif request == "date"
    9.   puts book.date
    10. ......

    如果用send方法的话,就简单多了:

    1. request = gets.chomp
    2.  
    3. if book.respond_to?(request)
    4.   puts book.send(request)
    5. else
    6.   puts "Input error"
    7. end

    这样不用在逐个对用户的输入进行测试,只要查询对象能否相应这个消息,再用send将输入直接发送给对象即可。

    通过 respond_to? 和 send 这两个方法,我们可以构造更灵活和稳定的程序。

  • 相关阅读:
    [日常摸鱼]UVA393 The Doors 简单计算几何+最短路
    [日常摸鱼]bzoj3122 [Sdoi]2013 随机数生成器
    [日常摸鱼]积性函数求和——杜教筛
    [OI笔记]NOIP2017前(退役前)模拟赛的总结
    [日常摸鱼]poj2417 DiscreteLoggingBSGS算法
    [日常摸鱼]UVA11424&11426 GCD Extreme
    [日常摸鱼]JSOI2008最大数
    [日常摸鱼]HDU1724 Ellipse自适应Simpson法
    原码、补码、反码的作用和区别
    Fibonacci序列or兔子序列
  • 原文地址:https://www.cnblogs.com/juandx/p/3985308.html
Copyright © 2011-2022 走看看