`

方法的动态调用

 
阅读更多
在Ruby中,有多种方法可以实现方法的动态调用。
1. 使用send方法
第一种实现动态方法调用是使用send方法,send方法在Object类中定义,方法的第一个参数是一个符号用来表示所要调用的方法,后面则是所调用方法需要的参数。
“This is a dog1″.send(:length) => 14
上面的代码中通过send方法去对一个字符串执行length操作,返回字符串的长度。

class TestClass
def hello(*args)
  ”Hello ” + args.join(‘ ‘)
end
end

a = TestClass.new
puts a.send :hello, “This”, “is”, “a”, “dog!”

执行结果为:
Hello This is a dog!

2. 使用Method类和UnboundMethod类
另一种实现动态方法调用是使用Object类的method方法,这个方法返回一个Method类的对象。我们可以使用call方法来执行方法调用。
test1 = “This is a dog1″.method(:length)
test1.call  => 14

class Test
def initialize(var)
  @var = var
end

def hello()
  ”Hello, @var = #{@var}”
end
end

k = Test.new(10)
m = k.method(:hello)
m.call   #=> “Hello, @iv = 99″

l = Test.new(‘Grant’)
m = l.method(“hello”)
m.call   #=> “Hello, @iv = Fred”

可以在使用对象的任何地方使用method对象,当调用call方法时,参数所指明的方法会被执行,这种行为有些像C语言中的函数指针。你也可以把method对象作为一个迭代器使用。
def square(a)
a*a
end

mObj = method(:square)
[1, 2, 3, 4].collect(&mObj)  => [1 4 9 16]

Method对象都是和某一特定对象绑定的,也就是说你需要通过某一对象使用Method对象。你也可以通过UnboundMethod类创建对象,然后再把它绑定到某个具体的对象中。如果UnboundMethod对象调用时尚未绑定,则会引发异常。
class Double
def get_value
  2 * @side
end

  def initialize(side)
   @side = side
  end
end

a = Double.instance_method(:get_value) #返回一个UnboundMethod对象
s = Double.new(50)
b = a.bind(s)
puts b.call

执行结果为:
100

看下面一个更具体的例子:
class CommandInterpreter
def do_2() print “This is 2\n”; end
def do_1() print “This is 1\n”; end
def do_4() print “This is 4\n”; end
def do_3() print “This is 3\n”; end
 
Dispatcher = {
   ?2 => instance_method(:do_2),
   ?1 => instance_method(:do_1),
   ?4 => instance_method(:do_4),
   ?3 => instance_method(:do_3)
}

def interpret(string)
   string.each_byte {|i| Dispatcher[i].bind(self).call }
  end
end

interpreter = CommandInterpreter.new
interpreter.interpret(’1234′)

执行结果为:
This is 1
This is 2
This is 3
This is 4

3. 使用eval方法
我们还可以使用eval方法实现方法动态调用。eval方法在Kernel模块中定义,有多种变体如class_eval,module_eval,instance_eval等。Eval方法将分析其后的字符串参数并把这个字符串参数作为Ruby代码执行。
str = “Hello”
eval “str + ‘ World!’” => Hello World!

sentence = %q{“This is a test!”.length}
eval sentence => 15
当我们在使用eval方法时,我们可以通过eval方法的第二个参数指明eval所运行代码的上下文环境,这个参数可以是Binding类对象或Proc类对象。Binding类封装了代码在某一环境运行的上下文,可以供以后使用。
class BindingTest
def initialize(n)
   @value = n
end

def getBinding
   return binding() #使用Kernel#binding方法返回一个Binding对象
  end
end

obj1 = BindingTest.new(10)
binding1 = obj1.getBinding
obj2 = BindingTest.new(“Binding Test”)
binding2 = obj2.getBinding

puts eval(“@value”, binding1)  #=> 10
puts eval(“@value”, binding2)  #=> Binding Test
puts eval(“@value”)     #=> nil

可以看到上述代码中,@value在binding1所指明的上下文环境中值为10,在binding2所指明的上下文环境中值为Binding Test。当eval方法不提供binding参数时,在当前上下文环境中@value并未定义,值为nil
分享到:
评论

相关推荐

    strurs2 入门 登录 参数请求 配置 方法动态调用易懂pdf资料

    本资料主要针对初学者,旨在帮助他们理解和掌握Struts2的基础知识,包括登录功能的实现、参数请求、配置、方法动态调用以及相关的标签库和拦截器。 一、Struts2入门 Struts2是Apache软件基金会的开源项目,它是基于...

    C#动态调用类方法

    1.动态调用类方法,模拟VB中的CallByName 2.附带了C#和VB的代码 3.主要是一个项目中用到了要调用很多参数和返回值相同的一系列函数,所以 想到了这个方法,不用重复的写方法名,使用循环调用

    java动态调用方法

    Java动态调用方法是Java反射机制的一个重要应用,它允许我们在程序运行时,根据需要动态地获取类的信息并调用其方法。这种能力为代码的灵活性和可扩展性提供了强大的支持,尤其在处理不确定的对象类型或者需要在运行...

    Struts2 动态方法调用(十三)

    在Struts2中,动态方法调用(Dynamic Method Invocation,DMI)是一种特性,允许我们通过URL直接调用Action类的方法,而无需在配置文件中显式指定。这在某些情况下提供了更大的灵活性。 在Struts2的动态方法调用中...

    webservices动态调用方法

    【动态调用 WebService】在.NET Framework中,动态调用Web Service是一种灵活的方法,尤其适用于那些在运行时才知道要调用哪个服务或服务地址的情况。这种方法避免了提前生成客户端代理类的限制,使得程序更加适应...

    webservice的动态调用和静态调用

    在开发中,我们通常会遇到两种调用方式:动态调用和静态调用。这两种方法各有特点,适用于不同的场景。 静态调用是通过在项目中添加Web引用或者服务引用来实现的。这种调用方式在编译时就已经确定了服务接口,因此...

    Struts2动态方法调用

    在Struts2中,JavaScript可以用来发起Ajax请求,动态调用后台Action的方法。例如,我们可以使用jQuery的`$.ajax`或`$.post`方法,配合Struts2的ActionContext,将请求参数传递给服务器。在服务器端,Struts2会解析...

    动态调用Web Service

    该方法将根据提供的参数动态调用Web Service并返回结果。 第二个InvokeWebService方法的参数包括Web Service的URL、类名、方法名和参数数组。该方法将根据提供的参数动态调用Web Service并返回结果。 在使用...

    delphi动态调用Dll

    在Delphi编程中,动态调用DLL(Dynamic Link Library)是一种常见的技术,它允许你在运行时加载和使用库函数,而无需在编译时硬编码这些依赖。这为程序提供了更大的灵活性,因为你可以根据需要加载特定的DLL,或者在...

    动态调用webservice.doc

    在代码中,可以通过一个名为`IniConnList`的静态方法动态获取这些连接。这个方法会读取App.Config中的`webType`值,并根据该值加载相应的WebService连接到一个字典中。这样做的好处是,可以根据运行时的需求选择调用...

    LabVIEW静态和动态调用子VI经典示例

    在提供的压缩包文件中,包含了“动态调用子VI.aliases”、“调用子VI.llb”、“动态调用子VI.lvlps”和“动态调用子VI.lvproj”这四个文件。这些文件分别对应: - 动态调用子VI.aliases:可能包含子VI的别名,方便...

    wcf动态调用

    wcf 用代理类的方法动态调用,不用去引用直接使用,使用的方法全在类注释上面。

    易语言API动态调用子程序源码

    在易语言中,API动态调用子程序是一项重要的功能,它使得开发者可以灵活地使用Windows API来扩展易语言的功能。 API动态调用子程序的核心在于“动态”二字,这意味着在程序运行时,可以根据需要加载并调用相应的API...

    C#_.NET_动态调用webservice的三种方式

    C# _.NET_动态调用webservice的三种方式 在本文中,我们将讨论如何动态调用WebService的三种方式。在某些情况下,我们可能需要在程序运行期间动态调用一个未知的服务。这可以通过使用.NET Framework的System.Web....

    解析及动态调用Webservice程序

    动态调用Webservice是指在运行时根据需要创建并执行Web服务的方法,无需预先编译或硬编码调用的详细信息。这种灵活性允许开发者在不完全了解服务接口的情况下使用服务,只需知道服务的URL和WSDL(Web服务描述语言)...

    反射动态调用DLL方法,含参数

    在给定的场景中,“反射动态调用DLL方法,含参数”意味着我们要通过代码动态地调用DLL库中的特定方法,并且能够传递参数。下面将详细解释这一过程以及涉及的关键知识点。 1. 反射(Reflection): 反射是.NET框架...

    C#动态调用WebService服务

    本文将深入探讨如何在C#中实现动态调用WebService服务,主要涉及"反射"和"动态调用"这两个核心概念。 首先,我们要理解什么是WebService。WebService是一种基于开放标准(如SOAP、WSDL和UDDI)的,可以在不同操作...

    C#动态调用Dll中的方法

    本主题将深入探讨如何利用C#的反射特性来动态调用DLL(动态链接库)中的方法。首先,我们需要了解什么是DLL以及它在程序中的作用。 DLL(Dynamic Link Library)是Windows操作系统中的一个共享库,它包含了一组可...

    详解Golang利用反射reflect动态调用方法

    ### Golang 反射 Reflect 动态调用方法详解 #### 一、引言 反射是许多现代编程语言中的一项重要特性,它允许程序在运行时检查和操作自身的内部结构。Go 语言同样具备这样的能力,它通过 `reflect` 包提供了一套...

    JavaBean 方法的动态调用

    在JavaBean中,动态调用方法是一种强大的功能,允许我们在运行时决定调用哪个方法,这主要通过Java的反射机制实现。 反射是Java语言的一个重要特性,它允许程序在运行时检查类的信息,包括类的结构、方法、字段等,...

Global site tag (gtag.js) - Google Analytics