免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: __BlueGuy__
打印 上一主题 下一主题

[C] Lua 造成的代码冗余太严重了, 这个现状怎么改善? [复制链接]

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
11 [报告]
发表于 2012-11-17 23:39 |显示全部楼层
回复 22# __BlueGuy__


    这就是问题了。

梵高,如果不去画画,如果去做苦力啊包工头什么的,会饿死么?

艺术需要某种病态的偏执。

正常情况下来说,你满足生存基本需要了,才会去想艺术,你饭都吃不饱,怎么去艺术?艺术是以生存为基础的上层建筑。

然而,就有些人,的确饭都吃不饱,但是也想做艺术,他们是在以生命为代价做艺术。

这两种人做的都是艺术。而如果你饭吃饱了/或者没吃饱,反正你做艺术的目的是为了吃饭,那么你做的就是商品,而不是艺术。

游戏是艺术的一种表现形式。如同电影。

我们类比上面的说法。

做游戏需要某种偏执。

正常情况下来说,你技术牛逼,思维敏捷,才能去做游戏。你连C都用不好,写个屁的游戏?游戏是以高级技术和创意为基础的上层建筑。

然而,就是有些人,技术不好,创意贫乏,但是也想做游戏,他们是用生命去做游戏。

这两种人做的都是游戏,而如果你只是为了骗傻逼,为了圈钱,反正做游戏的目的是为了赚钱,那么你做的是商品,而不是游戏。

游戏是一种商品,但商品不都是游戏。如同电影。

你要明白,你做出来的东西,是带着灵魂的。而商品是没有灵魂的。

不反对把商品做成艺术品,但是好歹那得是个艺术品。你不能打着艺术品的幌子卖商品,这种东西也没人买。

这就是为什么国内游戏地位微妙的原因。一来国人愚昧,傻逼哪儿都有,东西只要做出来就会有人给钱。游戏本质上不是在做游戏,在做炫耀,在做社区,在做富二代的约炮场地。游戏不是为了让人感到快乐和成就感而去做的。游戏是为了给那些想炫耀自己有钱和想约炮的人一个平台而作的。这种游戏观本质上是社会价值观扭曲造成的。二来,既然游戏只要出来了就能赚钱,那么就不谈游戏质量了。游戏只是一个平台,不是以一种艺术,所以也不需要管什么技术高超创意牛逼了,只要营销运营好就OK。

这就是中国游戏业的现状。网游的发展基本上宣判了游戏艺术的死刑。——现在大家都没饭吃,但是随便拉一坨粑粑都能赚钱,那谁会去傻逼了做木雕?等到大家都有饭吃了,即使拉一坨粑粑照样能赚钱,也会有人无聊了想做木雕的。这就是艺术的来源。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
12 [报告]
发表于 2012-11-18 00:34 |显示全部楼层
回复 27# __BlueGuy__


    所以要有信仰啊!别整些程序就是数学这种无用的东西,脑海里面抽象一下整个架构,幻想一下数据的流动,很有用的。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
13 [报告]
发表于 2012-11-18 00:48 |显示全部楼层
回复 25# OwnWaterloo


    好吧,先澄清一点:Lua的数据本身除了其“独立性”以外,没有其他的别的区别了,对程序员来说,就本质而言,io.open返回的东西和coroutine.create返回的东西,程序员是完全看不出区别的。说白了大家都是void*。所以我才说Lua的接口只有函数。file或者coroutine,只是函数在某个不透明指针上的表现而已,本质上还是函数作为接口,file或者coroutine只是函数的**上下文**。

然后就是,Lua模块的惯例(从Roberto和Luiz发布的模块作为标准,Lua社区默认执行)是,C模块,比如xxx.dll,所有导出的接口都是公开的。即xxx.foo,xxx.bar,只要有,就是公开的,而对于Lua模块,只有主接口是公开的。除非文档说明。Python也是一样的(主接口是__init__.py,其他的是否公开由文档说明,默认是不给你用的),任何对Lua有一定了解的人都知道这个规则——————问题是,你看看这个帖子吧,很多人对Lua一知半解就开始用,你让我怎么说好??

我问你,char*类型本身不管指向的内存是啥,要分配内存才能用,但是有些人就是对C一知半解,然后写:

char *buff;
strcpy(buff, "hello");

然后执行成功了!然后就一直这么用了,我问你这种人你怎么办?你怎么办?稍微学了一点C的人都不会这样吧?都知道这样的问题吧?问题就是用Lua的很多人对Lua的了解就只到这个水平就开始用Lua,你是怪Lua还是怪人呢?

现在的C编译器对这种用法有警告了(buff未初始化),但是Lua到这一步还有很长的路要走,其实也是有警告的,LuaInspect会给这种警告,但是刚刚学Lua的人又怎么知道LuaInspect的存在呢?就如同刚刚学C的人,又怎么看得懂C编译器给出的警告呢?(未初始化?什么叫未初始化?不懂,算了不管他了……)

Python的import的确会导致泄漏问题。比如说你有个os模块,你在里面会用到sys模块的内容:

# os.py
import sys
....

然后你载入os模块
import os
dir(os)

你会发现里面有个项叫"sys"……对,就是这样……你自己去看Python2.7,现在还是这个样子的!然后有些人就可能把sys当作os的某个interface来用了,我最开始的时候也干过这个事儿!但后来才知道,这实际上这只是个实现手段而已!Lua就不会有这样的问题……

是否默认导出神马的,一个良好实现的Lua,是根本不会有这样的问题的。导出的只有函数,而没有上下文,上下文由new给出,用setmetatable和函数绑定。以这种方式使用是不存在有“私有内容不允许你用”这种问题的。最多就是这个模块的接口没有稳定。大多数的动态语言其实都有这个问题。Lua对此也没有语言层面的解决方案(连模块系统都不是语言层面的,你还想要什么?)

就比如C对char*到底是否指向一个合法的地方是没有语言层面的强制方案的,你必须自己遵守规则,而且这些规则还有些暧昧不清(pm的那个关于二维数组的帖子)。你是可以说是C不好,可是事实就是这样,你咋办?你说语言不好?然后你就自己去发明一个?(你现在就在这么做了)

搞清楚一门语言的哲学和折中吧。不遵守语言的游戏规则,你怎么做都是错。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
14 [报告]
发表于 2012-11-18 09:45 |显示全部楼层
回复 34# OwnWaterloo


    Lua这种语言,不可能过多的把精力关注在模块系统上。Haskell的module,import都是语法。Lua怎么办呢?

实际上,Lua5.1的require允许你传递额外参数,所以如果你真就喜欢隐藏参数了,这么干吧…………

主模块:

local function private(module)
   if name_is_private(module._NAME) then error("private module") end
   return module
end

然后载入的时候:

require("xxxx", private)

不过这个特性在5.2被去掉了,所以……………………

更严重的是,无论你做什么手脚,无论你是不是私有的,模块载入这个行为是全局的,这就意味着,无论是否私有化,无论是否本地化,无论你用任何方式载入的这个库,只要你载入一遍了,你就可以在毫不修改任何默认参数的情况下require第二遍。因为被载入的库会被缓存,第二次载入根本不会再进入模块载入功能了,会直接加载缓存的那个库。也就是说,相对路径载入,根本达不到hide module的功能。你最终载入了plugin.foobar,用户会发现他突然能载入一个“神秘”的模块,叫做plugin.foobar了,而且很好用!突然有个版本这个神秘模块没了,用户傻逼了。

3的答案是不行,Lua没有遍历路径的任何方式。因为ANSI C没有。

4reload理论上做得到,云风就做到了。但是那意味着必须非常非常小心地写模块和框架,要有非常严格的语法限制,具体要花时间总结,而且有一点很重要的是,标准模块机制没用了。或者至少是得做大幅度修改。

我想说说我的观点。BASIC里面有goto,确切地说,1980年的GW-BASIC里面**只有**goto,所以产生了不少面条代码。所以你说goto是坏的,goto是恶魔。到了2012年的今天,有人听到了“goto是恶魔”这句话,于是就说“C语言里面goto是恶魔”,愚昧不?

C里面指针乱指导致内存泄露,于是人们说“Haskell内存不安全,指针乱指容易泄露”,傻逼不?

为什么一门语言的缺陷,就必须是所有语言的缺陷呢?

C模块容易造成安全性的私有模块的问题,仅仅在C模块——因为那在Lua能力范围之外。所以,你有选择是否导出的权利——确切地说,你只有明确地导出才能用。这避免了你喝醉了酒误加了一个参数然后把某个模块公开了——这不可能。你至少得写一打代码做导出。

而Lua模块。为什么我最开始说Lua导出的只有函数?是因为Lua的函数不危险。它们没有上下文。或者说,他们的上下文是死的,是文件里面写死的。Lua的模块机制是“平”的。即使你写a.b.c.d.e.f,到了module.loaded里面也是平的。平的模块机制是无法解决隐藏模块的问题的,也不需要解决隐藏模块问题。Lua无意隐藏任何模块。因为你只要拿出来的模块,就可以公开,出问题了是谁的问题呢?前面说了,社区啥啥啥的。语言为什么要强制某些东西呢?特别的,在Lua这种连参数数目都不强制,连变量声明都不强制的语言里面,你去强制不允许载入某些模块,你不觉得很可笑么?

Lua的哲学是“平面的比递归的好,显式的比隐晦的好”。所以Lua的模块机制是扁平的,Lua的模块载入是显式的(不允许一次载入多个模块如import ..plugins.*这种)。但是,Lua的哲学还有一个“做得到比做不到好”,因此你可以自己实现你想要的模块载入机制——啊啊啊,我知道你想说什么事情了。“这不标准”“你不能强制每个人都用你写的模块载入”,对不对?两个错误。1.Lua的模块机制对模块的要求是最低的。唯一要求是“你得返回你的模块内容”,Over,因此任何人实现的任何模块载入机制,都兼容所有人写的Lua模块。2.事实上有人已经做了,而且得到了官方承认。Lua邮件列表大概一两个月前很热烈的讨论了require的诸多可能,好像还创建了一个项目叫llrequire还是啥的,反正加了很多他们(自以为)很帅的功能,其中就有你的reload——虽然这不现实。

reload的问题,详细说说——你得保证所有模块的使用不会被缓存。就这么简单。但是也不简单。这意味着效率无法得到保证。无论中间加抽象层,还是用查表法调用函数,效率上都无法保证。所以我倾向于不依赖reload,或者在特定的机制上(仅依赖少数接口)的模块进行reload。

Lua的第一设计目标是嵌入式语言,简单是压倒一切的要求。第二设计目标里面,Lua的哲学阻止了实现所谓的私有模块和一次载入一户口本的模块。第二设计目标里面,Lua哲学允许你自己实现这些东西,而且和通用模块兼容,你还想要什么呢?——哦,对了,Lua还提供了实现这些东西的“砖瓦”,无论是package.loadlib(载入dll文件)还是package.searchpath(搜索一系列路径)都给你了,简直就是司马昭之心路人皆知啊………………那你还不动手?

其实自己设计一套载入机制也没什么太大问题,但这是一种很危险的信号:你在将其他语言的经验放入Lua。为什么不按照Lua的思路来,显式地、平面地去载入模块,不要去载入自己不知道的模块呢?如果你知道某个模块,你载入了他,下个版本他消失了,你难道不能从旧版本拷贝一个,放回来么?谁阻止你这么做了呢?

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
15 [报告]
发表于 2012-11-18 15:34 |显示全部楼层
回复 36# OwnWaterloo


    这不是代价不代价的问题。dofile的执行环境本身可能根本就不在某个file里面。dofile需要自己去查找这个函数的可能file再去判断啥的。理论上也做得到(你看到了),但是代价是很大的。更何况5.2的新功能(调试信息可能被strip掉),就更加不可能了。你见过C里面有个函数能在运行时取字符串name所指代的变量内容的么?没错,有调试信息的话做得到,但是没有呢?dofile面临的基本上就是这个问题。

Python为什么做得到?因为这个货所谓的strip模式strip掉的是注释……注释……其他的我就不多说什么了。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
16 [报告]
发表于 2012-11-18 15:37 |显示全部楼层
回复 37# OwnWaterloo


    又不是不要你用dofile,只是这货用来做require的活儿始终觉得不正统——对,我就是希望写出来的代码越正统越好。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
17 [报告]
发表于 2012-11-18 15:43 |显示全部楼层
回复 41# OwnWaterloo


    你喝醉酒了?你看清楚条件行不行?我还刚刚好给高亮过了你还没看见?不是说支持私有模块可笑,也不是说对载入私有模块给错误可笑。是说在一门“连参数数量和变量声明初始值都不会做报错处理”的语言中,“让载入私有模块报错是很可笑的事情,麻烦你看清楚前提,好吗?

顺便回上一个帖子没提到的部分,dofile依然没有解决报错的问题。dofile你自己可以do,但是你依然不会妨碍到别人天真地require,除非你改个扩展名,叫stm/atomic.private好了,你不觉得这样解决问题很自欺欺人么?但是,如果你不改后缀名,人家照样可以require 'stm.atomic',就算你自己dofile了也是这样!

再回一下,对Lua来说repl就不是官方考虑的内容!很多人都考虑过repl,甚至有过好多个实现(我知道的就有四五个)。但这不代表这就必须是官方考虑的内容了。说实话,我根本就没看懂你说的reload是什么含义。但是,不管如何,你到底是在使用Lua,还是站在clojure的制高点上嘲笑Lua?——哦,其实你根本就没用也没打算用Lua,对不对?这和站在路边嘲笑给乞丐扔钱的人有啥区别?

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
18 [报告]
发表于 2012-11-18 15:46 |显示全部楼层
本帖最后由 starwing83 于 2012-11-18 15:52 编辑

回复 43# OwnWaterloo


    除非强制要求debug信息必须存在——就像Python那样——否则你是做不到的。

Python也不是一直存在,Python的spec一直很暧昧,现在都没一个标准化的描述出现。所以说不准哪天你就boom了,很正常的,Python不兼容前面的实现也不是一次两次了——这不是说不兼容不好,是说dofile载入相对路径文件本身对语言来说就是很无理的要求。——你自己的文件结构,凭什么要语言帮你管?如果说编译器让你管,这个我赞同,问题是这货是运行时的啊!

编辑一下,Python本身有个import ..xxxx这样的语法,不知道是怎么实现的,也不知道如果我在buffer里面载入(类似Py_DoBuffer)的话这个执行会怎样,报错还是什么。所以我也不好说什么。

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
19 [报告]
发表于 2012-11-18 15:47 |显示全部楼层
回复 44# OwnWaterloo


    可是我有这样的需求,不好意思。你尊重我的需求么?你的态度和上次我说你的需求无理取闹有何区别?

论坛徽章:
5
狮子座
日期:2013-08-20 10:12:24午马
日期:2013-11-23 18:04:102015年辞旧岁徽章
日期:2015-03-03 16:54:152015亚冠之德黑兰石油
日期:2015-06-29 18:11:1115-16赛季CBA联赛之新疆
日期:2024-02-21 10:00:53
20 [报告]
发表于 2012-11-18 15:48 |显示全部楼层
回复 38# OwnWaterloo


    那些程序本身就跟Lua无关。

想要wildcard?自己用lfs去,Lua本身的确与wildcard无关,这就是事实。

dofile也不支持wildcard的,Lua没有任何一个部分支持wildcard,除非你自己写,这就是事实。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP