内容简介:今天我在推特上看到一条引起我注意的推文:出于科学的考虑,Erlang的私有函数是私有的!这与Python中的情况不同,在Python中,
今天我在推特上看到一条引起我注意的推文:
出于科学的考虑,Erlang的私有函数是私有的!这与 Python 中的情况不同,在Python中, 你在各处添加了几个下划线 ,突然之间,两秒钟前是私有的,现在已经公开了。在Erlang,我们的私有函数在保险箱里安全地呆了25年!没有人可以调用我们声明为私有的函数!或者……有办法吗?
事实证明,在Erlang中调用私有函数的方式并不那么简单,即使假设代码已经在启用 debug_info 的情况下编译。 让我们看看事情是如何运作的。
我们首先定义一个名为test的模块。 该模块包含两个函数,其中只有一个被导出:
-module(test). -export([public/0]). public()-> i_am_public. private()-> i_am_private.
让我们编译模块,并确保包含调试信息。 注意在Erlang中如何包含调试信息是相当常见的,因为包括调试器,交叉引用工具和覆盖分析工具在内的许多 工具 都需要这些信息才能工作:
$ erlc +debug_info test.erl test.erl:8: Warning: function private/0 is unused
编译器通知我们该私有函数不可访问,这是预期到会有的。 现在让我们打开一个 shell 并尝试调用这两个函数:
$ erl Erlang/OTP 19 [erts-8.3.5.3] [...] Eshell V8.3.5.3 (abort with ^G) 1> l(test). {module,test} 2> test:public. i_am_public 3> test:private(). ** exception error: undefined function test:private/0
我们可以调用公共函数,但不能调用私有函数。没什么新鲜的。现在,让我们定义一个小的匿名函数(我马上将解释它的作用),并将其绑定到变量Open:
4> Open = fun(Module) -> Which = code:which(Module), {ok,{_,[{_,{_,A}}]}} = beam_lib:chunks(Module, [abstract_code]), {ok, Module, Binary} = compile:forms(A, [export_all]), code:load_binary(Module, Which, Binary) end. #Fun<erl_eval.6.118419387>
然后让我们调用Open函数,将test模块作为参数传递给它:
5> Open(test). {module, test}
现在让我们尝试访问私有函数:
6> test:private(). i_am_private.
保险箱现在大开着。
那么,Open函数背后有什么样的黑魔法? 实际上并不多。 让我们再看一遍:
fun(Module)-> Which = code:which(Module), {ok,{_,[{_,{_,A}}]}} = beam_lib:chunks(Module, [abstract_code]), {ok, Module, Binary} = compile:forms(A, [export_all]), code:load_binary(Module, Which, Binary) end.
在向code server请求test模块的绝对文件名路径之后,我们使用强大的beam_lib接口从test模块的beam文件中包含的调试信息中提取抽象语法形式(还记得我们使用debug_info选项编译它吗?),然后我们从这些语法形式开始重新编译模块,并添加臭名昭著的export_all选项,这将导致导出模块中定义的所有函数。我们重新加载了模块的新版本。
为了简单起见,在上面的例子中有一些情况是Open函数没有考虑的,但你应该明白它的要点。
快乐黑客!
原文链接: https://medium.com/about-erlang/how-private-are-erlang-private-functions-36382c6abfa4
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- JavaScript 新语法详解:Class 的私有属性与私有方法
- 实战maven私有仓库三部曲之二:上传到私有仓库
- 实战maven私有仓库三部曲之三:Docker下搭建maven私有仓库
- 项目招标 中国移动廊坊私有云资源池SDN系统集采开启,进一步私有云池扩容
- docker私有仓库搭建
- 私有链可能没有未来?
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。