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 这两个方法,我们可以构造更灵活和稳定的程序。

  • 相关阅读:
    微信小程序HTTPS
    微信商城-1简介
    va_list
    Event log c++ sample.
    EVENT LOGGING
    Analyze Program Runtime Stack
    unknow table alarmtemp error when drop database (mysql)
    This application has request the Runtime to terminate it in an unusual way.
    How to check if Visual Studio 2005 SP1 is installed
    SetUnhandledExceptionFilter
  • 原文地址:https://www.cnblogs.com/juandx/p/3985308.html
Copyright © 2011-2022 走看看