看完《实用程序员》一书后,我发现最有趣的论点之一是“编写代码编写代码”。

我尝试在网上搜索更多有关以下内容的解释或文章尽管我找到了一些不错的文章,但仍然没有找到任何特定的代码实现或良好的示例。

我觉得它仍然不是一个普遍的论点,缺少文档或它没有被很多人接受,我想对此有所了解。

您如何看待这个主题?它会真正提高您的生产力吗?


一些代码示例将不胜感激,以使我能更好地理解其实现。


以下是该主题的Wiki页面,其中包含各种相关的编程技术,例如元编程,生成式编程和代码生成。

评论

我曾经写过写代码的代码,写过代码的代码... :)

@Benjol:您是用Lisp写作的吗?

此外,服务器端语言始终通过生成HTML,CSS和JavaScript来执行此操作。您可能有一个服务器端脚本,该服务器端脚本创建了一个服务器端脚本,该服务器端脚本使用创建更多html的javascript来创建html,而由于它的普遍性,没人会对此加以关注。

如果还没有,请阅读以下IBM developerWorks文章系列:“元编程的艺术”第1部分,第2部分和第3部分。

AtomWeaver(atomweaver.com)是自动编程的一个很好的例子:首先,您在Lua中创建可重用的微型程序。然后,通过重用这些资产来对系统建模。然后AtomWeaver编织一个Lua程序,其中包含您的“微型发电机”以生成系统的最终源代码。然后,您可以调整模型并重新生成。

#1 楼

在Lisp世界中,看到编写代码的代码和编写代码的代码(等等)是很常见的。因此,任何大小合适的Lisp或Scheme项目都将成为一个很好的代码示例。我建议查看Racket编译器和运行时源以及Bigloo,它们的库非常出色。

关于生产力:在几乎所有开发工作中,我都将元编程用作一种主要技术,这显然可以起到很大的帮助,既可以减小代码大小,又可以提高其可读性。关键在于使用领域特定语言,而元编程是实现它们的最有效方法之一。

#2 楼

我喜欢更进一步,而不是编写代码而不是编写代码,而是编写生成对象,方法和函数的代码。例如,这可以通过Lisp宏或Ruby动态程序修改功能来实现。

区别不在于您不会以自动生成的源文件结尾。通常,这些文件不是人类可读的,并且无法修改,所以为什么要打扰他们。我不喜欢使用无法控制的内容来增加代码库的想法。

我喜欢阅读的一本书是关于元编程Ruby(如果您知道Ruby语言的话)


在注释中回答以下问题后,请进行编辑:


为什么我仍然必须对生成的代码进行编码,这有什么用?我是否应该编写一个能够根据用户输入生成不同内容的代码,以便可以一遍又一遍地重用它?


首先,元编程不是目标,而是工具。不要使用元编程,因为“很酷”或“ X表示每个开发人员都应该使用元编程”。

我认为使用元编程的一个很好的理由是概括一些常见的模式(将模式重复出现)在代码中发现的代码,其他任何常规编程技术(继承性,设计模式等)都无法实现。

乔丹说过,一种典型的用例是数据库处理和ORM(对象)关系映射)。再次,在Ruby中,您应该查看ActiveRecord,它是应用于ORM的元编程的一个很好的例子。

作为最后的注释:

不要以为“我想Apply metaprogramming,我可以在代码中应用它吗?”。

认为“我看到这种模式在我的代码中反复出现,我找不到一种将代码重构为更小的代码的方法。更可重用。也许元编程可以帮助我吗?“

评论


@Jose:最常见的是您通过模板生成代码。例如,有apache(N-)速度或Visual Studio T4模板。然后,您只有一个程序,可以将元数据输入到模板中并从那时开始创建新文件。这很容易,我一直在做以生成UI骨架,实体等。

–猎鹰
2011年8月26日在8:57



@Jose Faeti,仔细研究Lisp宏(或Clojure或Nemerle,具体取决于您的平台首选项)。

– SK-logic
2011年8月26日在8:59

我将添加元编程可以替换某些模式,例如策略或状态,但没有运行时成本。这不仅针对通用重构无法解决的问题,而且有时是更好的选择。

–deadalnix
11年8月26日在17:18

@Jose Faeti:我知道您知道一些Python。它也具有元编程功能,尽管我没有真正使用过。看看Dangerously Advanced Python PDF

–套件
11年8月27日在12:48



@Falcon:IMO是生成代码的最糟糕的方法;对于没有内置元编程功能的语言,这是非常差的解决方法。与其生成Java或C#,不如以更高级别的JVM或.NET语言编写该代码。

–kevin cline
2012年8月10日17:18

#3 楼

更好的是,使用别人编写的代码来为您编写代码。

代码自动化通常对于ORM和其他数据库交互代码很有用,当然对于重复但相似的代码构建也是如此。 >
当然,如果您要构建很多外观相似的类,也许您可​​以更快地用动态语言完成相同的事情,但是我离题了。

这是尽管人们经常会发现该软件被标记为代码生成器,但它却受到了很多人的欢迎。

查看诸如CodeSmith和MyGeneration之类的公司和产品,或浏览以下Wikipedia文章:http:// en。 wikipedia.org/wiki/Comparison_of_code_generation_tools

评论


这没有什么好。您自己的宝贵的很少的代码无法由其他bloke的代码生成工具正确管理,因为其他bloke对您的细节一无所知。元编程最有效的用途是实现领域特定的语言-顾名思义,它们特定于您的问题领域,除您之外,其他任何人都无法实现。

– SK-logic
2011年8月26日在8:57

@ SK-logic:ORM生成的代码如何?它是由另一个工具/库生成的,仍然可以满足许多项目需求。

–大卫
2011年8月26日在9:26

@David,老实说,我对通用ORM并不十分信服。过去,我在使用它们时遇到了很多问题,通常是依靠实现我自己的特定ORM来实现。

– SK-logic
11年8月26日在9:41

@Jordan,所有这些工具都太具体了(更糟糕的是,基于文本,即在设计上逊色)。我是在谈论正确的元编程。

– SK-logic
2011年8月26日14:27



@AtillaOzgur,它们可以是“很好”,是的。但是它们并不比eDSL好。与宏元编程相比,独立代码生成显然受到更多的限制,灵活性也大大降低。

– SK-logic
2012年8月7日在8:49

#4 楼

lex和yacc是经典示例之一。它们的主要目的是避免编写任何类型的解析器的繁琐工作。一路走来,它们使构建具有许多规则和状态的复杂解析器的速度大大提高,而且还避免了人们自己翻滚自己所犯的所有意外错误。

这也是c背后的想法,这是编写汇编程序的工具。对于您想命名的任何高级语言而言,这也是一样。对于为您编写代码的工具,有一些简单的范例。

适当的IDE可以帮助您提供唾手可得的文档,智能自动完成功能和代码段。 IDE还包括各种模板,因此您不必从头开始编写程序。有一些程序可以绘制一个uml图并以一种高级语言来粗化类。

最后,您可以在自己的问题集中编写自己的代码生成工具。这就是lex和yacc第一次开始的方式。正是由于这个原因,存在任何一种特定于领域的语言。您创建了一些构建块,这些块以易于理解的代码,简单的命令包装了常见的活动或复杂的部分来描述您的解决方案。您并不是在寻找解决所有问题的解决方案,而只是在寻找要处理的特定问题的简便定义。

从某种意义上讲,您在二进制层之上所做的一切都是代码自动化。

评论


这是一个非常好的观点。总而言之,这只是程序员尝试用来促进其操作并专注于更高级别的编码(而不是语法代码详细信息)的众多方法中的另一种。

–乔斯·法蒂(Jose Faeti)
11年8月26日在13:01

@Jose Faeti Wikipedia文章en.wikipedia.org/wiki/Automatic_programming具有指向各种不同工具的链接,如果您对更多详细信息感兴趣的话。我还建议您阅读lex和yacc,因为关于它们的文档和说明很多。

– Spencer Rathbun
11年8月26日在13:24

在功能足够强大的语言(例如C ++而不是C)中,不需要lex和yacc之类的外部工具。

–kevin cline
2011年12月5日下午4:11

YACC不会编写“任何类型的解析器”。它编写了一种特定类型的解析器(LALR),如果没有自动帮助,它很难实现。还有另一种类型的解析器(递归下降),它更容易编写和正确使用,并且相应地更容易阅读和理解正在发生的事情。

–梅森·惠勒
2012年8月10日18:39



@MasonWheeler解析器的种类是指可以为广义,非精确意义上的问题解决而创建的语法。一年后阅读它,并没有我想要的那么清晰。我不确定我是否同意LL(*)解析器更容易编写和使用。

– Spencer Rathbun
2012年8月10日18:59



#5 楼

元编程

元编程是许多商店中有争议的技术。原因是,像任何强大的工具一样,帮助或伤害的程度也很大。

专业人士


更多的表达方式,更少的代码编写和维护(通常数量级或更多)
一致性,使用代码解决的问题类别上的行为更加一致
生产力,解决较大问题空间所需的代码更少

缺点


复杂性,即使代码较少也可能非常复杂
安全性,有时会牺牲类型安全性和静态分析
错误影响更多,小错误将产生更大的影响

我是元编程的忠实拥护者,但是我已经做了很长时间了。对我来说,减少代码大小和保持一致行为的权衡远不能弥补风险。更少的代码意味着更少的错误,更少的代码维护,而且我通常可以非常快速地添加大量功能。

但是,这并不意味着我认为所有程序员都应该参与其中。我已经看到并且不得不解决元编程所产生的大问题。通常从不了解概念并尝试扩展功能或仅修复错误的人开始。它需要一种特定的思维方式,至少要注重细节。使用元编程技术的问题应由团队决定。如果您的团队成员不了解,没有脾气,或者只是反对它,那么任何团队都不应该使用元编程。

评论


感谢您的有用考虑!您能建议我使用元编程来实现一个非常简单且基本的任务吗?这将使我节省一些比普通代码少的时间,这是一个简单的代码示例?

–乔斯·法蒂(Jose Faeti)
2011年8月26日在16:20



哈哈,让我想起几年前与GCC发生的错误。 162行将错误消息显示在我的屏幕上。递归元编程FTW!

–deadalnix
2011年8月26日在17:20

元编程的复杂性被高估了。只要使用正确的工具,其中绝对没有复杂的东西。而且DSL比典型的样板代码容易调试和维护。而且,我不明白为什么要牺牲类型安全性-恰恰相反,DSL也可能具有特定于域的高效类型系统。

– SK-logic
2011年8月26日在20:36

@ SK-logic:并非所有语言都支持元编程。因此有时会牺牲诸如类型安全性之类的东西(即C)。元编程也不只是DSL。它包括诸如调度样式编程,泛型,currying,对象检查,动态应用程序之类的东西。至于复杂性,我认为对我们(具有元编程经验的人)说起来并不复杂。我在理解所有将在其下执行代码的情况下还遇到了其他困难。这主要取决于他们的经验和所涉及的技术。

–dietbuddha
2011年8月26日在21:14



@dietbuddha,请您详细说明一下,无论如何实施,为什么都要牺牲自己的DSL的安全性?您可以在具有强大类型系统的纯C语言中编写临时解释器(例如,参见Hugs)。您可以编写一个针对C的代码生成器,该代码生成器自己进行所有类型检查,而不依赖目标语言类型系统。出于复杂性考虑:大多数人都以不必要的复杂方式进行操作,而所有相同的设计方法都可以像“常规”编程中那样应用于代码生成。几乎不需要新知识。

– SK-logic
11年8月28日在10:33

#6 楼

大多数代码编写代码。例如,PHP代码有助于编写html。 php pdo库可帮助编写SQL调用。文件I / O功能编写代码以与OS通信。甚至常规的函数调用都引用了另一个要执行的代码块。因此,您的函数调用就是编写代码。

广义上,我们可以将计算视为编写代码,该代码以递归方式编写代码,从而形成一个堆栈,当堆栈遇到连接到硬件的代码的物理现实时,该堆栈终止。

评论


我不会将html称为编程语言。它是文档的语法

–西蒙·贝格(Simon Bergot)
11年8月28日在10:42

@Simon有趣的一点。我们使用的不同代码具有各种各样的表达能力。代码可以用较弱的语言,较强的语言或它自己的语言编写。

– Ben Haley
2011年8月28日14:14



#7 楼

您的操作方式因您的要求而异。假设您使用的是静态代码生成,则可以自己编写所有基础结构,也可以使用现有的生成器,例如CodeSmith或MyGeneration。使用这些,您只需要编写所需的模板即可。

我涉及的最后一个项目是一些基本的ASP.NET CRUD屏幕(代码生成对此非常有用)。该过程将实体定义为xml文件中的元数据。编写模板以涵盖所需的各种工件(实体类,存储库,服务类,asp.net控件,asp.net页面等)。运行生成过程并设置输出的样式。

编写模板有一些开销,但是可以将它们重新用于后续的类似项目。类似地,通过更改元数据并重新运行生成,可以处理基础数据的更改,从而使更改更容易,更快捷地实现。

用于测试。由于这是模板系统,因此您将需要花费一些时间来最初验证流程的输出,如果模板错误,则该模板的所有输出也将同样错误。一旦对此感到满意,还可以使用代码生成器从xml元数据创建基本测试,然后将其扩展以涵盖特殊情况。但是请记住,您可能仍需要进行代码测试以适应特定的情况,代码生成会减少您的工作,但并不能完全消除它。

#8 楼

在我们公司,我们使用一些工具,这些工具实际上使用从互联网下载的数据生成C ++或C#类。这些类是数据容器,并且在列表中包含大量对象。

评论


例如,在某些IDE(例如Visual Studio)中找到的代码片段?

–乔斯·法蒂(Jose Faeti)
2011年8月26日14:53

@Jose我们的工具只是一个将HTML输出转换为类的应用程序。因此,与其每次应用程序启动时不下载数据,我们都下载一次并制作一个类。

–霍利(Holli)
2011年8月29日在7:41

#9 楼

元编程已经是编程的一部分了。不仅要考虑诸如SWIG之类的工具或创建代码的所见即所得的设计器,还要考虑诸如C的预处理器甚至C ++的模板以及C#/ Java的泛型之类的语言工具,更不用说反射了。

实际上,您可能会争辩说每个编译器只是另一个元程序-他们采用程序文本以及输出机器或VM代码。而且,没有编译器的生活?哎呀。

评论


没错,但是您如何才能实际使用自己的编程语言来实现它以真正提高生产力呢?那就是我所缺少的。

–乔斯·法蒂(Jose Faeti)
11年8月28日在12:48

#10 楼

这是我过去的一个具体示例。

我在一个使用BDE进行数据访问的站点上使用Delphi源代码约50MB。他们想切换到使用Direct Oracle Access来允许Oracle升级到BDE支持的最高版本(如果我没记错的话,升级为8i)。

因此,而不是让一组编码人员来工作每个表单和数据模块都需要手动更改每个组件,我编写了一个PERL脚本,该脚本:-


解析DFM(表单文件)并标识了所有TQuery,TTable,TStoredProcedure和TDatabase对象-将项目存储在列表中。
解析PAS(代码)并确定对象的用途-TQueries是在进行更新还是选择?同样,它可以识别用代码创建的所有对象,而不是放在IDE中的表单上。
重写DFM和PAS,以适当地更改对象类型(例如TTable-> TOracleDataSet,将SQL属性设置为“ select * from”等)和方法调用。此外,如果合适的话,还添加了额外的方法调用来关闭,打开和设置参数。

简而言之,需要花3个星期的时间来调整脚本,使其能够在具有不同编码样式的不同团队编写的不同应用程序上工作,而不是最初估计有5个以上的开发人员工作了6个月。

我什至想到使用这种方法的原因是通过阅读The Pragmatic Programmer

评论


太好了,从现在开始我已经进入Perl了几天,我已经制作了一些生产力工具,只需键入“创建工作区”即可生成用于Web开发的基本工作区,以及所有目录,文件等! :)

–乔斯·法蒂(Jose Faeti)
2011年9月6日下午6:21

@Jose就是这个主意。使用脚本语言自动执行重复的内容。一次性可以将生产率提高8倍,或者在某些情况下要一次又一次地浪费时间。

– mcottle
2011年9月6日7:33

#11 楼

您需要提供示例。...

使用SQL时,您不应该直接更改数据库,而应该执行执行所需更改的脚本,包括对结构的更改。数据库(添加表,列,主键,约束等)。通常,您将需要同时对许多表或列执行相同的操作,并且一个接一个地执行它们将很乏味,这是一个简短的脚本,可以输出较大的脚本来满足您的实际需求。省时。

例如,在将DATE数据类型引入MS SQl Server之前,日期列的唯一选择是DATETIME,它具有一个时间部分-一个用于处理的时间部分数据有点难。升级到具有日期数据类型的版本后,您可能希望更新时间始终为00:00的列。在具有数十甚至数百个DateTime列的数据库中,这将非常耗时。但是编写一个查询所有表的脚本很容易,检查数据类型为DATETIME的每一列,看看时间是否是除00:00以外的时间,如果不是,则创建一个ALTER语句来更改表/列数据类型为DATE。 Presto,编写代码的代码。

#12 楼

元编程可能很难维护。乍一看,它看起来很优雅,但是当您开始遇到极端情况时,错误就会被捕获到很晚(在生成的代码上),并且整个事情成为使用/调试的噩梦。

我主要写过python代码,根据我的经验,元编程始终是使用这种语言的错误选择。您总是可以通过无聊的正常语言功能来重构事情。结果不那么时髦,但更易于使用。

评论


任何类型的代码都很难维护。如果采取正确的方法,可能会非常容易。实际上,元编程可以将可维护性提高几个数量级。您的python经验可能与真正的元编程无关,因为Python笨拙的AST太不适合这种思维方式。但是即使使用Python,我也可以高效地使用Tempita库,即使对于几乎没有Python经验的团队,也从未遇到任何可维护性问题。

– SK-logic
2011年8月28日上午10:57

我对您对python AST的观点很感兴趣。您是否已将tempita用于元编程?

–西蒙·贝格(Simon Bergot)
11年8月28日在16:33

这个(docs.python.org/library/ast.html)是一个特别的AST,并且解析器提供了未经优化的过大的树,这使分析成为问题(尤其是在Python中缺少适当的模式匹配)。生成这样的AST也不是很方便。我使用tempita来生成Python和C代码(即,基于纯文本的元编程),它可以很好地完成特定任务(样板代码生成)。我还经常使用Python从一些XML高级描述中生成C代码。

– SK-logic
11年8月28日在17:16

您能否指出一些您可能在基于文本的元编程方法中找到的论文或书籍?我正在尝试使用有点接近AST的对象图,并且觉得自己没有进步。

–德米特里·波尼亚托夫(Dmitry Ponyatov)
20年8月16日在7:18

#13 楼

看看CL(通用嘴唇)宏。我认为这正是您想要的。 Lips是元编程的完美之选。

我也建议Nemerle如果您想拥有具有完善的元编程支持(包括宏)的.NET功能

,但是如果您想要一个真正的代码,生成引擎看看Apache Thrift

#14 楼

我只是在开发这样的工具。在我们的特殊情况下,我们基于数据库中函数的签名为数据层生成VB.NET代码。

由于您没有这样的功能,开始时很难进行代码生成知道如何生成代码,但是一旦有了一套已建立的规则,并且始终可以根据这些规则生成必须生成的代码,那么使用该代码就不那么困难了。当然,根据代码生成的复杂性和规则的数量,任务可能会变得更加困难。但是从本质上讲,自动代码生成用于重复的编码任务,而不是用于变化很大的高级代码。

测试输出是双重的。首先,您必须确保代码可以编译,这很容易。然后,您必须确保输出根据生成的参数来执行其预期的工作。..的难度随生成的代码的复杂性而变化。

我的真诚的建议是,如果您觉得自己以重复的方式编写代码,并且可以负担得起的时间。请尝试考虑所生成的代码无法完成您正在做的事情。如果是这样的话(如果它是重复的代码,而几乎总是这种情况),请考虑您将要扩展多少次,对该代码稍加修改以及还要编写该确切类型的代码多少次。如果对这些问题的回答是“很多”,那么您应该认真考虑为该代码生成一个生成器。

希望有帮助,
IPP

评论


感谢您的回答!您的示例中的规则实际上是如何实施的?

–乔斯·法蒂(Jose Faeti)
11年8月30日在10:01

我无法告诉您所有规则,但可以举一些例子。我们解析oracle数据库公开的接口,并考虑oracle接口中功能的签名。基于签名,我们生成数据层函数的名称。我们知道,我们总是从数据库中获得一个oracle数据表,并将其解析并保存到用于存储数据的特殊对象类型数组中。同样,基于db函数签名的输入/输出参数,我们向生成的函数中添加相应的输入和输出参数,依此类推。

–伊安·保罗·皮劳(Ioan Paul Pirau)
11年8月30日在12:09

#15 楼

我有一个PHP模块,该模块输出一个包含生成HTML的JavaScript代码的网页。那是三层。小伙子真难读书!

在编程类中,我们不得不编写一个程序,该程序将从用户那里获取公式字符串并进行解析并显示值。最令人印象深刻的求解器只是简单地接受用户输入,将其包装在main(){printf(“%d”,...);}中,然后运行脚本进行编译,链接和运行。他没有写解析器!今天,您可以在SQL SELECT语句中做到这一点。

您应该使用它,然后将其存储起来以备将来使用。

评论


那实际上是我试图实现的东西! :)但是后来我决定离线使用Perl对其进行编码,并且效果很好。我有很多功能要添加!

–乔斯·法蒂(Jose Faeti)
2011年9月6日上午9:11

我正在编写多达20层语言到语言转换的代码,完全没有问题。它没有比20层的调用堆栈深度更复杂。因此,我强烈不同意它是一种“可以在将来方便使用的将来存储”的工具-代码生成始终很方便。

– SK-logic
2011年9月6日下午12:55

#16 楼

我用Prolog开发了简洁的元编程解决方案。主应用程序(用C ++表示)在运行时将问题的抽象定义转换为Prolog应用程序,然后委托给该应用程序。通常,用C ++编写等效功能会花费很多时间。

我认为这种情况是支持code-writing-code参数的绝佳案例。

#17 楼

您如何看待该主题?

元编程最常与非动态语言相关联,因为在实现某些行为(例如实现ORM)的过程中,如果没有很多非生产性的,非生产性的和难以实现的行为,则很难进行。非智能代码行。

但是,即使在诸如PHP之类的更动态语言中,代码生成也可以真正节省生命,并大量提高生产率。在现代框架中,使用脚手架为您声明的某个业务对象生成大多数通用模型,形式,测试和操作是非常普遍的。这是诸如symfony或RoR之类的框架取得如此巨大成功的原因之一,这些代码生成工具可以非常快速地生成一致的代码并提高程序员的生产力。

在网站上,大多数交互围绕四个主要操作:


创建元素
检索一组元素(可能进行过滤)
使用新属性更新元素
删除一组元素

至少可以围绕这四个主要动作进行所有操作,并且应该使用代码生成工具来实现恕我直言,以实现最大的生产力。

在我公司,我们使用symfony,它的admin-generator是一个出色的工具,它甚至可以在运行时生成代码(并将其缓存),这意味着我们甚至不需要使用任何类型的任务或外部工具即可生成新代码。 ,我们只需要清理缓存即可。我强烈建议使用这种工具进行CRUD操作。

但是,要做symfony出色的贡献者所做的事情并非易事。我已经实现了一些代码生成任务,并且要做到真正一致的事情,并且要实现涵盖大多数极端情况的广泛实现,这并不容易。

这真的可以提高您的生产率吗?

我相信元编程在较低级别的工作(框架,缓存,编译器等)中非常重要,但是如果要在业务层上进行操作,则必须格外小心。

毫无疑问,使用代码生成是提高生产力的主要动力。实现自己的代码生成工具,除非您自己构建框架,否则不需要做很多事情。

在书籍,博客,幻灯片等中,关于该主题有哪些好的资源?

了解程序设计的最佳资源始终是良好且注释良好的源代码。我想说,研究RubyOnRails和Symfony管理员生成器是一个好主意。

#18 楼

尽管这里有许多答案是指通常所说的元编程,但实际上有一个与AI相关的领域称为自动编程,它是关于程序理解或合成程序的[1]。

任何编译器(或元程序,代码生成器,翻译器,宏系统等)进行转换,通过执行其固定的转换算法从输入生成输出。但是,传统的编译器或元程序在给出列表排序的定义,描述或示例的情况下(例如[5,3,9] => [3,5,9])不会创建排序算法。此类问题是“自动编程”领域感兴趣的地方。

[1]-程序理解系统的进度报告
ftp://db.stanford.edu/pub/cstr /reports/cs/.../CS-TR-74-444.pdfShare

#19 楼

OP要求资源。

您可能会发现我们的DMS软件再造工具包很有趣。它是一种纯元编程工具,旨在让人们构建自定义程序分析和转换工具。

[要对OP的问题进行评论,当用于构建特定的转换工具时,DMS是产品线编写代码,编写代码:]

DMS通过与目标编程语言无关(但不独立)来实现这一目标。 DMS提供了各种元编程任务所需的标准服务,就像OS为标准编程任务提供了多种服务一样。这些服务包括强大的解析,表象语法树的自动构建,树上的模式匹配和重写,符号表库,它们可以使用讨厌的作用域规则轻松管理语言,例如多重继承,控制流,数据流,指向和调用图分析。在没有要处理的特定语言的情况下,这些都不是有意义的,因此DMS接受与这些通用机器相关的语言定义,从而产生特定于语言的解析,AST构造,特定于目标语言的模式匹配/使用目标-语言语法,特定于目标语言的分析器等。

和OS一样,DMS的设计对要编写的(元)程序几乎没有意见或约束,这意味着它可以用于多种目的:提取度量标准,查找无效代码,实施Aspect Weavers,翻译语言,从DSL生成代码,重新构造大型应用程序。 (DMS已经用于所有这些任务)。

如果您不想花时间对语言参考手册中的所有内容进行编码(请想一想这对Java和C ++意味着什么),则需要一个可靠的语言定义。 DMS通过提供完整的语言定义库来解决此问题。这里的模拟有点像为您的操作系统提供数据库。您不必实现其中之一即可继续编写以数据库为中心的应用程序。

#20 楼

请参阅MIT课程6.916:创新Web服务的软件工程(http://philip.greenspun.com/teaching/psets/ps4/ps4.psp)中的Philip Greenspun的问题集4。

它的目标说,“教学生元数据的优点。更具体地说,他们学习如何正式表示Web服务的需求,然后构建计算机程序以生成实现该服务的计算机程序。”

此是潜在的ArsDigita(http://en.wikipedia.org/wiki/ArsDigita)新兵在第一个泡沫期间需要解决的问题之一。

“ SQL for Web Nerds”一书Philip pset中的引用已移至(http://philip.greenspun.com/sql/)。

#21 楼

在2001年左右,我开始从事一个广泛使用业务对象和数据对象的项目。我本来要构建前端网站,但由于业务层和数据访问层尚未完全开发,因此不知所措。几周之后,我开始认真研究这些层在做什么。基本上,它们将存储过程返回的数据作为具有与数据字段对应的属性的对象集合进行公开,或者将输入参数发送给存储过程以保存到数据库表中。两层之间发生了许多序列化/反序列化,涉及到Microsoft Transaction Server,一个IDL / ODL类型库...但是都适合于模式。

2周后,我设计了一个代码生成器,它将生成IDL / ODL,也将生成业务和数据对象。花费了两年的时间来构建业务和数据层对象的人才能调试和测试这些对象。在两周的时间里,通过代码生成,我们得到了相同的输出,但是由于所有代码都生成了,因此它几乎没有错误。

代码生成器(低级CASE工具)跟随着我许多不同的迭代(大约8到10年),因为原理是如此简单:与数据库对话时您需要做的事情是重复的,这几乎是重复的编码,一旦正确就不会

所以,是的,请使用代码生成器,尤其是当代码重复且符合明确定义的模式时。

我已经已知的人使用RegX宏来执行类似的操作,或使用Excel公式来执行类似的操作(我也这样做)。

#22 楼

一个元编程示例

我有一个称为Authority的Ruby授权库。它使开发人员可以使用current_user.can_read?(@post)@post.readable_by?(current_user)之类的方法在其应用程序中提问。这些问题由集中的授权者类回答。

这是至关重要的部分:授权机构在看到用户的配置之前不知道要定义哪种方法。用户配置可能包含:

config.abilities =  {
  ...
  :read      => 'readable',
  :microwave => 'microwavable',  # user-defined
  ...
}


那种情况下,需要像current_user.can_microwave?(@post)这样的方法。

元编程使这成为可能:之后阅读配置,我知道要定义哪些方法:

Authority.verbs.each do |verb|
  class_eval <<-RUBY, __FILE__, __LINE__ + 1 # allows for a nice bracktrace
    def can_#{verb}?(resource)
      resource.#{Authority.abilities[verb]}_by?(self)
    end
  RUBY
end