热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Elixir-动态调用私有函数

如何解决《Elixir-动态调用私有函数》经验,为你挑选了2个好方法。

我发现Kernel.apply/3它允许通过将方法指定为原子来动态调用模块中的公共方法,例如result = apply(__MODULE__, :my_method, [arg])转换为result = my_method(arg)

困扰我的是一种称私人方法的方法; 给出这样的代码:

defmodule MyModule do
    def do_priv(atom, args) when is_list(args) do
        apply(__MODULE__, atom, args)
    end

    # (change defp => def, and this all works)
    defp something_private(arg), do: arg #or whatever
end

我希望这MyModule.do_priv(:something_private, [1])是允许的,因为它是从模块内部调用私有方法.我可以理解,引擎盖Elixir正在使用Erlang的apply/3,所以这种方法可能不会让我们在那里.

我也试过使用这个Code.eval_quoted/3方法,但它似乎甚至没有能够调用硬编码的私有方法(因此没有时间花在手上构建AST,而不是quote do像下面那样使用 - 尽管如果有人看到这是一个选项如何使这项工作):

defmodule MyModule do
    def do_priv_static do
        something_private(1) #this works just fine
    end

    def do_priv_dynamic do
        code = quote do
            something_private(1)
        end
        Code.eval_quoted(code, [], __ENV__)   #nope.  fails
    end

    defp something_private(arg), do: arg #or whatever
end

同样,它可以从包含模块中访问私有函数,所以我希望它是允许的.它可能我只是不明白__ENV__参数eval_quoted

唯一可行的解决方案,现在正在改变defpdef,这是我个人的代码精解; 但是既然我编写的代码支持其他关心的程序员,我想找到一个解决方案.

我对其他方法持开放态度,但我个人难以理解如何实现这一目标.



1> sasajuric..:

在Erlang中不能动态调用AFAIK私有函数(因此不能在Elixir中).如果需要进行动态分派,可以考虑使用多子句功能.一个人为的例子(肯定是一个糟糕的例子,但想不出更好的ATM):

iex(1)> defmodule Math do
          def operation(op) do
            IO.puts "invoking #{inspect op}"
            run_op(op)
          end

          defp run_op({:add, x, y}), do: x + y
          defp run_op({:mul, x, y}), do: x * y
          defp run_op({:square, x}), do: x * x
        end

iex(2)> Math.operation({:add, 1, 2})
invoking {:add, 1, 2}
3

iex(3)> Math.operation({:mul, 3, 4})
invoking {:mul, 3, 4}
12

iex(4)> Math.operation({:square, 2})
invoking {:square, 2}
4

另一个选择是公开您的功能,但表明@doc false它们是内部的 - 即不打算由客户公开​​使用.您还可以考虑将这些功能移动到单独的模块中,并将整个模块标记@moduledoc false为内部模块.两种方法偶尔用于Elixir代码中.

但是我建议开始简单,并使用模式匹配+多子句函数.如果代码变得更复杂,我会考虑其他选项.



2> Miroslav Pry..:

首先,您应该知道f()在MyModule模块中MyModule.f()调用的内容与在同一位置调用的内容不同.见http://www.erlang.org/doc/reference_manual/code_loading.html#id86422

您只能调用私有函数f()样式.这些调用也由编译器检查 - 如果该函数不存在,则会出现编译错误.当你MyModule.f()在同一个地方使用时,你不会得到编译错误,因为这些调用只在运行时检查(即使你从内部调用模块),效果是(AFAIK)就像你MyModule.f()从任何一个调用一样其他模块 - 在运行时查找模块,您只能调用导出(公共)函数.

因此,您不能以任何其他方式调用私有函数,而不仅仅是普通函数f().apply(mod,fun,[])mod.fun.()样式的等价物- 模块在运行时解析,私有函数不可访问.

您可以在此示例中自行尝试所有变体:https://gist.github.com/mprymek/3302ff9d13fb014b921b

你现在可以看到,在编译时必须始终知道对私有函数的调用,所以你甚至不能使用eval_quoted魔法或任何其他魔法来使它们"动态"......

Sasa Juric的使用建议@doc false是正确的解决方案.


推荐阅读
  • C++ 开发实战:实用技巧与经验分享
    C++ 开发实战:实用技巧与经验分享 ... [详细]
  • 技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统
    技术分享:使用 Flask、AngularJS 和 Jinja2 构建高效前后端交互系统 ... [详细]
  • 如何将TS文件转换为M3U8直播流:HLS与M3U8格式详解
    在视频传输领域,MP4虽然常见,但在直播场景中直接使用MP4格式存在诸多问题。例如,MP4文件的头部信息(如ftyp、moov)较大,导致初始加载时间较长,影响用户体验。相比之下,HLS(HTTP Live Streaming)协议及其M3U8格式更具优势。HLS通过将视频切分成多个小片段,并生成一个M3U8播放列表文件,实现低延迟和高稳定性。本文详细介绍了如何将TS文件转换为M3U8直播流,包括技术原理和具体操作步骤,帮助读者更好地理解和应用这一技术。 ... [详细]
  • PHP预处理常量详解:如何定义与使用常量 ... [详细]
  • 数字图书馆近期展出了一批精选的Linux经典著作,这些书籍虽然部分较为陈旧,但依然具有重要的参考价值。如需转载相关内容,请务必注明来源:小文论坛(http://www.xiaowenbbs.com)。 ... [详细]
  • 如何利用Java 5 Executor框架高效构建和管理线程池
    Java 5 引入了 Executor 框架,为开发人员提供了一种高效管理和构建线程池的方法。该框架通过将任务提交与任务执行分离,简化了多线程编程的复杂性。利用 Executor 框架,开发人员可以更灵活地控制线程的创建、分配和管理,从而提高服务器端应用的性能和响应能力。此外,该框架还提供了多种线程池实现,如固定线程池、缓存线程池和单线程池,以适应不同的应用场景和需求。 ... [详细]
  • 本文详细探讨了Zebra路由软件中的线程机制及其实际应用。通过对Zebra线程模型的深入分析,揭示了其在高效处理网络路由任务中的关键作用。文章还介绍了线程同步与通信机制,以及如何通过优化线程管理提升系统性能。此外,结合具体应用场景,展示了Zebra线程机制在复杂网络环境下的优势和灵活性。 ... [详细]
  • Web开发框架概览:Java与JavaScript技术及框架综述
    Web开发涉及服务器端和客户端的协同工作。在服务器端,Java是一种优秀的编程语言,适用于构建各种功能模块,如通过Servlet实现特定服务。客户端则主要依赖HTML进行内容展示,同时借助JavaScript增强交互性和动态效果。此外,现代Web开发还广泛使用各种框架和库,如Spring Boot、React和Vue.js,以提高开发效率和应用性能。 ... [详细]
  • 如何撰写初级和高级前端开发者的专业简历
    如何撰写初级和高级前端开发者的专业简历 ... [详细]
  • WebStorm 是一款强大的集成开发环境,支持多种现代 Web 开发技术,包括 Node.js、CoffeeScript、TypeScript、Dart、Jade、Sass、LESS 和 Stylus。它为开发者提供了丰富的功能和工具,帮助高效构建和调试复杂的 Node.js 应用程序。 ... [详细]
  • CTF竞赛中文件上传技巧与安全绕过方法深入解析
    CTF竞赛中文件上传技巧与安全绕过方法深入解析 ... [详细]
  • Squaretest:自动生成功能测试代码的高效插件
    本文将介绍一款名为Squaretest的高效插件,该工具能够自动生成功能测试代码。使用这款插件的主要原因是公司近期加强了代码质量的管控,对各项目进行了严格的单元测试评估。Squaretest不仅提高了测试代码的生成效率,还显著提升了代码的质量和可靠性。 ... [详细]
  • 本文介绍了 Vue 开发的入门指南,重点讲解了开发环境的配置与项目的基本搭建。推荐使用 WebStorm 作为 IDE,其下载地址为 。安装时请选择适合您操作系统的版本,并通过 获取激活码。WebStorm 是前端开发者的理想选择,提供了丰富的功能和强大的代码编辑能力。 ... [详细]
  • 如何精通编程语言:全面指南与实用技巧
    如何精通编程语言:全面指南与实用技巧 ... [详细]
  • SSAS入门指南:基础知识与核心概念解析
    ### SSAS入门指南:基础知识与核心概念解析Analysis Services 是一种专为决策支持和商业智能(BI)解决方案设计的数据引擎。该引擎能够为报告和客户端应用提供高效的分析数据,并支持在多维数据模型中构建高性能的分析应用。通过其强大的数据处理能力和灵活的数据建模功能,Analysis Services 成为了现代 BI 系统的重要组成部分。 ... [详细]
author-avatar
蚂蚁少校
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有