如何运行一个ruby类 中的方法

Python013

如何运行一个ruby类 中的方法,第1张

在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

end

def

do_1()

print

“This

is

1

end

def

do_4()

print

“This

is

4

end

def

do_3()

print

“This

is

3

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。

先安装rubyinstaller,下载并解压DevKit,注意,这两个版本要对应,网页上有说明(http://rubyinstaller.org/downloads/),解压DevKit后,打开目录,运行devkitvars.bat(是不是必须的不确定)。

打开cmd,进入DevKit的解压目录

ruby dk.rb

---

Configures an MSYS/MinGW based Development Kit (DevKit) for

each of the Ruby installations on your Windows system. The

DevKit enables you to build many of the available native

RubyGems that don't yet have a binary gem.

Usage: ruby dk.rb COMMAND [options]

where COMMAND is one of:

init prepare DevKit for installation

review review DevKit install plan

install install required DevKit executables

and 'install' [options] are:

-f, --force overwrite existing helper scripts

-------------

ruby dk.rb init

---

Initialization complete! Please review and modify the auto-generated

'config.yml' file to ensure it contains the root directories to all

of the installed Rubies you want enhanced by the DevKit.

--------------------------------

ruby dk.rb install

---

Invalid configuration or no Rubies listed. Please fix 'config.yml'

and rerun 'ruby dk.rb install'

如果出现的是这个,则需要修改config.yml

加入

- C:\Ruby200-x64

---

[INFO] Updating convenience notice gem override for 'C:/Ruby200-x64'

[INFO] Installing 'C:/Ruby200-x64/lib/ruby/site_ruby/devkit.rb'

这是对的

---------------------

gem install ruby-debug-ide

---

Temporarily enhancing PATH to include DevKit...

Building native extensions. This could take a while...

Successfully installed ruby-debug-ide-0.4.17

Parsing documentation for ruby-debug-ide-0.4.17

Installing ri documentation for ruby-debug-ide-0.4.17

1 gem installed