我是程序员;您好程先生;叫我序员就好了Ruby首页投稿(暂停使用,暂停投稿)

用Ruby你就是root

2016-07-26  本文已影响601人  lanzhiheng

1. 你会感觉你就是管理员

用过Mac或着Linux的朋友应该就有这样的感觉,如果你是root你就是上帝(God)。你可以对系统进行任何操作,包括直接删除系统的根目录。这种上帝的感觉真好。不过好归好,能力越大责任越大。如果你不幸得到了公司产品线机器的root权限,你就得对它的运行负责。
扯远了,相似的如果你要用Ruby这门语言你将拥有近似于root的权限。你可以修改这门语言的任何东西。甚至内置对象。这听起来可能会很不可思议。Python这些语言就会有一定的保护机制,我们原则上无法轻易破坏他们的内置函数。但是Ruby就不一样了。你可以随时随地地修改Ruby的内置函数,类等等。所以很多人都觉得Ruby这门语言十分适合那些禁得起折腾,又有一定的安全意识和编程经验的人--Hacker。Ruby究竟有多猛?破坏一个类究竟有多难?我们往下看。

2. 修改String类

这里只是举例来说明,不限于String类

class String
  def become
    return "good"
  end
end

p "lanzhiheng".become

结果:

good

上面这个例子很简单其他语言也可以做到类似的事情。但是注意了,这里我们定义的实例方法是属于String类的。它是Ruby里面的内置类,理论上应该是不允许修改的。但是,我们却可以很容易地修改它的值。当然还不仅仅是如此。

[7] pry(main)> String.instance_methods.grep /cat/
=> [:concat]

上面看到String 类的一个实例方法是 concat。我们试试这个脚本。

p "Hello".concat " World!!"
class String
  def concat(x)
    self + ", I'm a bug"
  end
  
end

p "Hello".concat " Good!!"

结果

"Hello World!!"
"Hello, I'm a bug"

我们甚至还可以修改原有的内置方法的定义。如果我们这个脚本先于其他脚本加载,而其他脚本如果都运用到这个concat方法的话,那就乱套了。这种修改类的方式我们业界给了专业术语叫做打开类。 另外,有些人不喜欢这种能够修改类本身内置对象的行为,所以给它取了个名字叫做猴子补丁

这样对于一些喜欢折腾的人固然是很好,而很多的程序员都能够驾驭这种能力。然而,肯定还是有人不满意。我们的Ruby社区是考虑地如此周到。从Ruby2.0开始加入了细化(refine)的功能,能够在一定程度上较少这种影响的范围。

module StringExtensions
  refine String do
    def concat(x)
      self + ", I'm a bug"
    end
  end
end



module StringStuff
  using StringExtensions
  p "Hello".concat " Good!!"
end

p "Hello".concat " Good!!"

现在的结果是

"Hello, I'm a bug"
"Hello Good!!"

只有在module中通过using引入细化过的类,才会影响原来实例方法的行为。而不会影响其他地方同名实例方法的行为。

3.修改字符串本身

注意这里是修改字符串本身,我们都知道Ruby的实例方法是可以带特殊符号的。有一特殊符号为!(感叹号)。如果方法后面带上它标示强制修改。我们看看下面这个例子

# 不加感叹号,则返回修改后的值a本身并没有变
[4] pry(main)> a = "be good at     "
=> "be good at     "
[5] pry(main)> b = a.strip
=> "be good at"
[6] pry(main)> b
=> "be good at"
[7] pry(main)> a
=> "be good at     "
# 加上感叹号,则返回修改后的值的同时,修改a本身
[8] pry(main)> a = "be good at     "
=> "be good at     "
[9] pry(main)> b = a.strip!
=> "be good at"
[10] pry(main)> b
=> "be good at"
[11] pry(main)> a
=> "be good at"

刚开始接触的时候我也觉得不可思议,因为目前我学过的语言只有C是有这种功能的。没想到Ruby居然支持这种行为。这也给一些有洁癖的,喜欢折腾的程序员带来了福音。反正我是觉得这个很酷。不知道你怎么想了-!!!

4.写在最后

总之,在用Ruby的时候我们是拥有那么高的权限。甚至有作者说

如果你心情不好去修改常量String,就能够把系统弄崩溃。

这么任性我喜欢。

我们也知道常量是赋值之后就不建议修改了。如果修改的话会有警告,但是并不会妨碍我们修改。所以当我们去修改String常量的时候:

[12] pry(main)> String = 12
(pry):12: warning: already initialized constant String
=>
(pry) output error: #<TypeError: can't define singleton>
[13] pry(main)> 2
SystemStackError: stack level too deep
....

错误栈能延伸到系统那层了。几乎整个系统都会用到String这个类,所以现在我的pry环境就不能用了,只能重新启动。希望你会喜欢上今天提到的Ruby特性。

今天就到这里。哦,不对,晚点应该还会有其他文章。

Happy Coding !! _

上一篇下一篇

猜你喜欢

热点阅读