Julia 把自己的代码表示为语言中的数据结构,这样我们就可以编写操纵程序的程序。
元编程也可以简单理解为编写可以生成代码的代码。
元编程(英语:Metaprogramming),是指某类计算机程序的编写,这类计算机程序编写或者操纵其它程序(或者自身)作为它们的资料,或者在编译时完成部分本应在运行时完成的工作。多数情况下,与手工编写全部代码相比,程序员可以获得更高的工作效率,或者给与程序更大的灵活度去处理新的情形而无需重新编译。
编写元程序的语言称之为元语言。被操纵的程序的语言称之为"目标语言"。一门编程语言同时也是自身的元语言的能力称之为"反射"或者"自反"。
-- 维基百科
1、解析原始 Julia 代码: Julia 解析器首先将解析字符串以获得抽象语法树(AST),AST 是一种结构,它以易于操作的格式包含所有代码。
2、执行已解析的 Julia 代码:: 在这个阶段,执行已解析的 Julia 代码。
当我们在交互式编程环境(REPL)中输入代码并按回车键时,会执行以上两个阶段。
使用元编程工具,我们就可以访问这两个阶段之间的 Julia 代码,即在源代码解析之后,但在执行之前。
Julia 提供了一个 Meta 类,其中可以用 Meta.parse(str) 来对一个字符串进行解析,用 typeof(e1) 返回 Expr:
返回 :(1 + 1) , 这个返回的值由一个冒号和后面的表达式组成,用 typeof(ex1) 返回 Expr。
Expr 对象包含两个部分(ex1 包含了 head 和 args 属性):
一个标识表达式类型的符号对象。
另一个是表达式的参数,可能是符号、其他表达式或字面量:
表达式也可能直接用 Expr 构造:
上面构造的两个表达式:一个通过解析构造,一个通过直接构造,两个是等价的:
Expr 对象也可以嵌套:
我们也可以使用 Meta.show_sexpr 查看表达式,以下实例展示了嵌套的 Expr:
我们可以通过冒号 : 前缀运算符存储一个未计算但已解析的表达式。
引用下面的整个表达式:
引用算数表达式:
注意等价的表达式也可以使用 Meta.parse 或者直接用 Expr 构造:
引用多个表达式也可以在 quote ... end 中包含代码块。
表达式解析后,我们可以使用 eval() 函数来执行:
抽象语法树 (AST) 是一种结构,是源代码语法结构的一种抽象表示。
它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。
我们可以在 dump() 函数查看表达式的层次结构:
使用值参数直接构造 Expr 对象虽然很强大,但与 Julia 语法相比,Expr 构造函数可能让人觉得乏味。作为替代方法,Julia 允许将字面量或表达式插入到被引用的表达式中。表达式插值由前缀 $ 表示。
在此示例中,插入了变量 a 的值:
对未被引用的表达式进行插值是不支持的,这会导致编译期错误:
julia> $a + b ERROR: syntax: "$" expression outside quote
在此示例中,元组 (1,2,3) 作为表达式插入到条件测试中:
julia> ex = :(a in $:((1,2,3)) ) :(a in (1, 2, 3))
在表达式插值中使用 $ 是有意让人联想到字符串插值和命令插值。表达式插值使得复杂 Julia 表达式的程序化构造变得方便和易读。
宏提供了一种机制,可以将生成的代码包含在程序的最终主体中。 宏将一组参数映射到返回的 表达式,并且生成的表达式被直接编译,而不需要运行时 eval 调用。 宏参数可能包括表达式、字面量和符号。
这是一个非常简单的宏:
宏在Julia的语法中有一个专门的字符 @ (at-sign),紧接着是其使用 macro NAME ... end 形式来声明的唯一的宏名。在这个例子中,编译器会把所有的 @sayhello 替换成:
:( println("Hello, world!") )
当 @sayhello 在REPL中被输入时,解释器立即执行,因此我们只会看到计算后的结果:
julia> @sayhello() Hello, world!
现在,考虑一个稍微复杂一点的宏:
这个宏接受一个参数 name。当遇到 @sayhello 时,quoted 表达式会被展开并将参数中的值插入到最终的表达式中:
我们可以使用函数 macroexpand 查看引用的返回表达式:
我们可以看到 "human" 字面量已被插入到表达式中了。
还有一个宏 @ macroexpand,它可能比 macroexpand 函数更方便:
几个月前,我读了一篇关于rubygem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:
网络编程套接字网络编程基础知识理解源`IP`地址和目的`IP`地址理解源MAC地址和目的MAC地址认识端口号理解端口号和进程ID理解源端口号和目的端口号认识`TCP`协议认识`UDP`协议网络字节序socket编程接口`sockaddr``UDP`网络程序服务器端代码逻辑:需要用到的接口服务器端代码`udp`客户端代码逻辑`udp`客户端代码`TCP`网络程序服务器代码逻辑多个版本服务器单进程版本多进程版本多线程版本线程池版本服务器端代码客户端代码逻辑客户端代码TCP协议通讯流程TCP协议的客户端/服务器程序流程三次握手(建立连接)数据传输四次挥手(断开连接)TCP和UDP对比网络编程基础知识
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
我创建了一个由于“在运行时执行的单例元类定义”而无法编码的对象(这段代码的描述是否正确?)。这是通过以下代码执行的:#defineclassXthatmyusesingletonclassmetaprogrammingfeatures#throughcallofmethod:break_marshalling!classXdefbreak_marshalling!meta_class=class我该怎么做才能使对象编码正确?是否可以从对象instance_of_x的classX中“移除”单例组件?我真的需要一个建议,因为我们的一些对象需要通过Marshal.dump序列化机制进行缓存。
我正在查看Ruby日志记录库Logging.logger方法并从sourceatgithub提出问题与这段代码有关:logger=::Logging::Logger.new(name)logger.add_appendersappenderlogger.additive=falseclass我知道类 最佳答案 这实际上删除了方法(当它实际被执行时)。这是确保close不会被调用两次的保障措施。看起来好像有嵌套的“class 关于Ruby元编程问题,我们在StackOverflow上找到一
使用Paperclip,我想从这样的URL抓取图像:require'open-uri'user.photo=open(url)问题是我最后得到一个像“open-uri20110915-4852-1o7k5uw”这样的文件名。有什么方法可以更改user.photo上的文件名?作为一个额外的变化,Paperclip将我的文件存储在S3上,所以如果我可以在初始分配中设置我想要的文件名就更好了,这样图像就会上传到正确的S3key。像这样:user.photo=open(url),:filename=>URI.parse(url).path 最佳答案
我正在开发一个xcode自动构建系统。在执行一些预构建验证时,我想检查指定的证书文件是否已被撤销。我了解securityverify-cert验证其他证书属性但不验证吊销。我如何检查撤销?我正在用Ruby编写构建系统,但我对任何语言的想法都持开放态度。我阅读了这个答案(Openssl-Howtocheckifacertificateisrevokedornot),但指向底部的链接(DoesOpenSSLautomaticallyhandleCRLs(CertificateRevocationLists)now?)进入的Material对我的目的来说有点过于复杂(用户上传已撤销的证书是一
关闭。这个问题是off-topic.它目前不接受答案。想改进这个问题吗?Updatethequestion所以它是on-topic用于堆栈溢出。关闭11年前。Improvethisquestion我不经常使用ruby-通常它加起来相当于每两个月或更长时间编写一次脚本。我的大部分编程都是使用C++进行的,这与ruby有很大不同。由于我与ruby之间的差距如此之大,我总是忘记语言的基本方面(比如解析文本文件和其他简单的东西)。我想每天练习一些基本的东西,我想知道是否有一些我可以订阅的网站,并且会向我发送当天的Ruby问题或类似的东西。有人知道这样的站点/Internet服务吗?
我一直在寻找一种以编程方式或通过命令行将mp3转换为aac的方法,但没有成功。理想情况下,我有一段代码可以从我的Rails应用程序中调用,将mp3转换为aac。我安装了ffmpeg和libfaac,并能够使用以下命令创建aac文件:ffmpeg-itest.mp3-acodeclibfaac-ab163840dest.aac当我将输出文件的名称更改为dest.m4a时,它无法在iTunes中播放。谢谢! 最佳答案 FFmpeg提供AAC编码功能(如果您已编译它们)。如果您使用的是Windows,则可以从here获取完整的二进制文件。
我想输入一个字符串并返回一个可用于描述字符串结构的正则表达式。正则表达式将用于查找更多与第一个结构相同的字符串。这是故意模棱两可的,因为我肯定会漏掉SO社区中的某个人会发现的情况。请发布任何和所有可能的方法来做到这一点。 最佳答案 简单的答案(可能不是您想要的)是:返回输入字符串(正则表达式特殊字符转义)。这始终是与字符串匹配的正则表达式。如果您希望识别某些结构,则必须提供有关您希望识别的结构类型的更多信息。如果没有这些信息,问题就会以模棱两可的方式陈述,并且有许多可能的解决方案。例如,输入字符串'aba'可以描述为'阿巴''阿巴*