https://coolshell.cn/articles/3585.html
嗯?HTTP 动词又使用 POST,不是 GET,好像你把信封放那,别人不是有时间了看一下回你,还是立刻就回复一样
就算 GET 有 body 和请求长度上限制算吧,可既然用了 POST,Status Code 不用又是什么意义?
如果只是把 HTTP 当成管道来用,为什么不抽象出一个底层的 SOAP-HTTPTUN 协议?
我的天啊,现在还有人觉得序列化是很重要的东西?难道这不像小白觉得 JavaScript、Lua 和 Ruby 有本质上的区别一样可笑吗?序列化和数据本身无关,和表达格式有关!难道二进制读写器这类东西需要额外再写,不是很差劲的主意吗?
基于文档和 KV 有啥关系和不同???所谓的文档是什么?redis 的 geolocation, sorted set, bitmap, lru 算不算?
……当一个东西的复杂性需要工具来解决,那些复杂性就本不应该存在。
就像一些人谈编程,他们根本不知道自己写了半天 Java、C,自己写的是什么,更不可能知道 C 的前身是 BCPL、第一个广泛使用的高级语言 Fortran 是 John Backus 于 1957 设计的,更不可能知道自己在用的基础编程方法是『表述式』,结构化编程,是对过程的结构化描述,那时编程是用既有的数据、程序逻辑和语言提供的结构,组织自己的程序,事件、线程、异步,这些通通不特殊。
其实我设计过一种『WSDL』,它的名字叫 GeekSpec,虽然那时我还很幼稚,我肯定我的设计思想是简单的。
getUserList(name_filter:string) -> array:user = /users
POST@createUser(name:string) = /users
没人会用的设计,会引发非常严重的问题。
WSDL 居然是一种『语言』?它是工具生成的?
这就显示出它的不成熟,早产儿。
SOAP专家: 不知道,使用GET的行为 undefined.
程序员: 哼哼。那么,要是我把我的服务移到别的 endpoint上?我是否可以得到一个301错误?
SOAP专家: 不会的,SOAP不会返回HTTP的错误码。 嗯?HTTP 动词又使用 POST,不是 GET,好像你把信封放那,别人不是有时间了看一下回你,还是立刻就回复一样
就算 GET 有 body 和请求长度上限制算吧,可既然用了 POST,Status Code 不用又是什么意义?
如果只是把 HTTP 当成管道来用,为什么不抽象出一个底层的 SOAP-HTTPTUN 协议?
SOAP专家: RPC!对象序列化!你从哪得到的SOAP就是一堆RPC的这种印象?! SOAP是关于基于文档的消息传递啊,我的朋友。 我的天啊,现在还有人觉得序列化是很重要的东西?难道这不像小白觉得 JavaScript、Lua 和 Ruby 有本质上的区别一样可笑吗?序列化和数据本身无关,和表达格式有关!难道二进制读写器这类东西需要额外再写,不是很差劲的主意吗?
基于文档和 KV 有啥关系和不同???所谓的文档是什么?redis 的 geolocation, sorted set, bitmap, lru 算不算?
SOAP专家: 忘了我所说的吧。现在,让我们谈谈消息传递吧。其消息格式遵守XML Schema,我们把之称为新型的文件格式。
程序员: XML Schema?
SOAP专家: 哦,这是很不错的东西,未来的头等技术,你应该看一下。
程序员: (阅读 Schema 规格说明书). 上帝保佑我们!就算是亚历山大帝也搞不定它啊。
SOAP专家: 不必太担心。会有专门的工作为你来创建XML Schema。真的,这只不过就是工具上的事。 ……当一个东西的复杂性需要工具来解决,那些复杂性就本不应该存在。
就像一些人谈编程,他们根本不知道自己写了半天 Java、C,自己写的是什么,更不可能知道 C 的前身是 BCPL、第一个广泛使用的高级语言 Fortran 是 John Backus 于 1957 设计的,更不可能知道自己在用的基础编程方法是『表述式』,结构化编程,是对过程的结构化描述,那时编程是用既有的数据、程序逻辑和语言提供的结构,组织自己的程序,事件、线程、异步,这些通通不特殊。
SOAP专家: 哦,我没有说过吗?WSDL. Web Services Description Language. 它让你指定你的数据类型,参数,操作名,传输绑定,以及endpoint URI,这样,所有的客户程序员就可以访问你的服务了。你应该看看。 其实我设计过一种『WSDL』,它的名字叫 GeekSpec,虽然那时我还很幼稚,我肯定我的设计思想是简单的。
getUserList(name_filter:string) -> array:user = /users
POST@createUser(name:string) = /users
程序员: (阅读WSDL 规格说明书)。我相信那个写下这个文章的人已经被枪杀了。其内部说明都不一致。而且,其用的是HTTP GET绑定,你不是和我说过, GET 是 undefined吗.
SOAP专家: 不必担心那个,没人会用那玩意。 没人会用的设计,会引发非常严重的问题。
总之,工具会帮你生成WSDL,而且在WDSL里会有Schema的。 WSDL 居然是一种『语言』?它是工具生成的?
SOAP专家: 就像是原来那样,只不过,你整个消息被 包装起来成一个元素,其和操作有一样的名字。现在操作名和消息成了一体了。 这就显示出它的不成熟,早产儿。
程序员: 让我总结一下,SOAP的定义是不变的,SOAP可以是任何东西,但就是简单,它不再意味着对象访问,就算是所有的工具都那样做。
SOAP专家: 基本上是对的,但是我们走得比你要远一些。我们不赞成SOAP缩写的含义。
程序员: 真的!那么SOAP是什么的缩写?
SOAP专家: 什么也不是,就是SOAP.酷 壳 - CoolShell
SOAP的S是Simple | 酷 壳 - CoolShell
duangsuse::Echo
所以我们在能够区分 case 制造 Element Tree 之前,还需要一个 Map<string, [PlaygroundDefaults, PlaygroundFnGlobalId, PostprocessFn]> 其中 PostProcessFn 可以帮助一些与 #Kotlin Playground 对元素树的结构要求区别很大的 playground 完成兼容,比如修改 hidden text area 的 class 什么的。 #project type PlaygroundDefaults…
什么叫做『设计』呢?举个例子吧。就是上面这种情况,为什么我不用之前想的扩展配置结构:
而换用更『不规范』的
我们来看看它们是怎么被使用的,我们有一个钩子函数
而且我们用了 RequireJS,模块化了 JavaScript 代码,这已经是很『出尘脱俗』的做法了,为什么在这种情况下不允许外部脚本复用 'dom' 这个 JavaScript module?为了兼容老一点的编程风格?
Map<string, [PlaygroundDefaults, PlaygroundFnGlobalId, PostprocessFn]> 而换用更『不规范』的
Map<string, [ElementConfig, Operation<Element>]> 呢?我们来看看它们是怎么被使用的,我们有一个钩子函数
function configureLiterateKotlin()。它会在为整个页面添加 show code button 之前对 LiterateKt Script 进行配置。function configureLiterateKotlin() {
// 『更规范的方法』 [PlaygroundDefaults=Object, PlaygroundGlobalId=String, Postprocess=ElementConfig]
literateKtConfig.language["kotlin"] = [
{/**/},
"KotlinPlayground",
() => {},
];
首先我们就不该写 Postprocess——为什么?难道不应该和前面的 assignDOMAttribute 合并吗?能放在一起的为什么不放一起?能更加可配置的为什么还要用一个全局函数的名字,并且强求那个函数只有一个 (e_code:Element) 参数?而且我们用了 RequireJS,模块化了 JavaScript 代码,这已经是很『出尘脱俗』的做法了,为什么在这种情况下不允许外部脚本复用 'dom' 这个 JavaScript module?为了兼容老一点的编程风格?
// 正常方法 [ElementConfig, Operation<Element>]这是我的编程风格,避免任何含糊和“自动类型转换”。
const { withAttribute } = require('dom');
literateKtConfig.language["kotlin"] = [withAttribute({/**/}), e => schedule("KotlinPlayground", e)];
}
type Operation<T> = Consumer<T>
[DuangSUSE@duangsuse]~% find . -print -perm a+x
这也太难用了吧! tldr!还有 bitflags,7 是 rwx,从 x 到 w 居然是 1 2 4!
这也太难用了吧! tldr!还有 bitflags,7 是 rwx,从 x 到 w 居然是 1 2 4!
for ln in $<.each_line do好久以前的 #Ruby
next unless ln.start_with?('mv')
_mv, src, dst = ln.split
puts("mv #{dst} #{src}")
end
def bulkRename(re_src, pat_dst, fmt_dst)
re_dst = Regexp.new(pat_dst)
selected = Dir.glob(re_src)
for name in selected
newnam = name.gsub(re_dst, fmt_dst)
puts("mv #{name} #{newnam}")
File.rename(name, newnam)
end
end
case ARGV.size # Just br size is OK
when 0 then warn("Usage: #{$0} [select] re_dst fmt_dst")
when 1 then puts(Dir.glob($*[0]))
when 2 then bulkRename('*', $*[0], $*[1])
when 3 then bulkRename($*[0], $*[1], $*[2])
end
duangsuse::Echo
for ln in $<.each_line do next unless ln.start_with?('mv') _mv, src, dst = ln.split puts("mv #{dst} #{src}") end def bulkRename(re_src, pat_dst, fmt_dst) re_dst = Regexp.new(pat_dst) selected = Dir.glob(re_src) for name in selected newnam =…
for ln in $<.lines do
if ln.start_with?("mv"); next; end
_mv, src, dst = ln.split
puts("mv #{dst} ${src}")
end —
def bulkRename(pat_glob, pat_src, fmt_dst)
names = Dir.glob(pat_glob)
for name in names do
newName = file.gsub(pat_src, fmt_dst)
puts("mv ${name} {newName}")
end
end
case ARGV.size
when 0 then warn("Usage #{$0} [select] pat_src [fmt_dst]")
when 1 then puts(Dir.glob(ARGV[0]))
when 2 then bulkRename("*", ARGV[0], ARGV[1])
when 3 then bulkRename(ARGV[0], ARGV[1], ARGV[2])
end垃圾 NVIDIA 驱动 DKMS depmod 每次都不能用,需要更新内核时重新 install!而且现在还构建失败了!不知道是为什么,说是没有 Module.symvers 文件……