summaryrefslogtreecommitdiff
path: root/content/weekly/60.md
blob: 88e80a88b413eebb5ab41e15c354bcb8f57e5329 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
+++
title = "稻草人周刊 Vol.60"
subtitle = "我加入了 Fediverse 和 IndieWeb"
tags = [
    "软件",
    "自由软件",
    "语言",
    "Web",
]
date = 2025-12-22T08:37:00
draft = false
toc = true

+++

{{< music cover="https://img.eltr.ac/uPic/2025/12/coffee-cantata.webp" title="咖啡康塔塔" artist="巴赫" apple="https://music.apple.com/cn/album/bach-coffee-cantata/1452223774" >}}

康塔塔(Cantata)是一种古典乐形式,也叫做「清唱套曲」,是一种包含独唱、重唱、合唱的声乐作品,一般包含多个乐章,大多有管弦乐伴奏。[^1]咖啡康塔塔[^2]是巴赫在 1732 到 1735 年创作的作品,尽管叫做康塔塔,但其实更像是短小的歌剧,而且偏喜剧。

故事的内容是一位父亲想要改掉女儿每天喝咖啡的*恶习*,威胁她要是不停止喝咖啡,就不准她参加派对、不准上街、没有新裙子穿,女儿说要是能喝咖啡,怎么样都行。最终父亲忍无可忍,说要是不戒掉咖啡,就不给女儿找男人,女儿说要是能找到一个健硕的爱人,自己就不会喝咖啡——最后,女儿偷偷地传播消息:要是不在婚约上写自己可以想什么时候喝咖啡就什么时候喝,自己就不会嫁给他。

我真的很喜欢这段歌词,我想我会背诵下来的 😋

> *If I couldn't, three times a day, be allowed to drink my little cup of coffee, in my anguish I will turn into a shriveled-up roast goat.* <br/>
> 如果我每天不能美美喝上三次咖啡,我就会痛苦得像一只被炙烤的山羊。
>
> *Ah! How sweet coffee tastes, more delicious than a thousand kisses, milder than muscatel wine.* <br/>
> 啊!咖啡尝起来多甜美!比一千个情人的吻还美味,比麝香葡萄酒更温柔!
>
>*Coffee, I have to have coffee, and, if someone wants to pamper me, ah, then fill up my coffee again!* [^3]<br/>
> 咖啡啊咖啡,我一定要喝,如果有人要款待我,就请满上我的咖啡杯!

<!--more-->

## ⋈︎ · 连接

### 怎么哪里都有菜单图标?

> [!note] 📜
> [Icons in Menus Everywhere — Send Help - Jim's Blog](https://blog.jim-nielsen.com/2025/icons-in-menus/)

作者抱怨了 macOS Tahoe 在菜单栏里加图标的新设计,他一直认为菜单栏里的图标是一种视觉噪音,看起来很乱,而且可能造成误解。许多产品(比如 Google Sheets)都采用了这种设计,而随着 macOS Tahoe 发布,Apple 也加入了「硬往菜单里塞图标」的大军,他感到很沮丧。

作者认为用于移动窗口、管理窗口布局的图标,用图形来指示位置是很直观的,是好的设计,然而,如果没有好的理由,就不应该往菜单里塞图标。讽刺的是,Apple 实际上违背了他们自己的[设计指导](https://web.archive.org/web/20201027235952/https://developer.apple.com/design/human-interface-guidelines/macos/menus/menu-anatomy/),相关的文档中有一节专门讨论图标在菜单中的使用。

> There are a few standard symbols you can use to indicate additional information in menus…Don’t use other, arbitrary symbols in menus, because they add visual clutter and may confuse people.
>
> 有一些标准的符号可以用在菜单中指示附加信息。不要在菜单中随意使用其他的符号,因为它们可能会造成视觉杂乱、使人困惑。

我也不喜欢菜单里硬塞图标的设计(还有在 PPT 里塞语义模糊、与上下文无关的图标),我认为这种设计本质上是缺少思考的体现,没有考虑设计是否必要,只是想要把空间占满,明明**有些空白就应该留着**。

### 开发者应该如何命名工具?

> [!note] 📜
> [Programmers and software developers lost the plot on naming their tools](https://larr.net/p/namings.html)

作者观察到了一种现象:如今的软件开发者非常喜欢用动物、虚构角色和一些意义不明的名词来命名自己的软件,像 Cobra、Viper 和 Melody,使得整个软件生态变得像是动物园,最大的问题是,这让那些排查依赖问题的开发者很头疼,看着长长的依赖树却根本不知道每个依赖是用来做什么的。作者指出,其他科学领域里不会把这种命名方式视作专业行为——如果一个化学家把一个分子命名为 Steve,仅仅因为 Steve 这个名字很好笑,而且会让他的论文更接地气,这无异于社会性自杀。

作者指出,以前的软件名称都有表意作用,比如早期的编程语言名字:

- FORTRAN(Formula Translation)
- COBOL(Common Business-Oriented Language)
- Lisp(List Processing)

还有早期的 Emacs 编辑器里的一些名字,dired 是 Directory Editor(目录编辑器)、eshell 是 Emacs Shell;一些命令也是如此,比如 grep 是 Global Regular Expression Print(全局正则表达式打印),sed 是 Stream Editor(流编辑器),cat 是 Concatenate(串联)。

作者认为动物园式的命名方式会造成认知债务(cognitive tax),使开发者不得不花更多的时间来理解工具的名字。他认为软件开发者应该使用复合词,根据用途来命名软件,至于宣传和接地气的部分,完全可以单独做一个吉祥物,比如 PostgreSQL 的吉祥物是一只名叫 Slonik 的大象——不要把软件的名字当成吉祥物。

---

我其实不能**完全**认同作者的观点。实话实说,在读这篇文章之前,我完全不知道 grep 的全名是「全局正则表达式打印」而 Emacs 里的 dired 是目录编辑器——这几个东西我都用过,`grep` 还是我最常用的命令之一,然而,它们的名字对我而言,和 Cobra、Viper 之类的没有太多区别。作者可能忽略了,许多人(尤其是非英语母语者)并不在乎一个工具的全名是什么,只要把用途和名字匹配起来就好了——所有程序员都会写 SQL,但除了学校里的老师可能会在 PPT 上写「SQL 的全名是 Structured Query Language,结构化查询语言」之外,还有多少人在乎呢?像 MySQL 和 PostgreSQL 这样的数据库管理系统,明明不是一种 DSL 或者 SQL 的变体,却还是使用了 SQL 的名字,这个词已经变成广义上的关系型数据库的代称了。

更别提 FORTRAN、COBOL 和 Lisp 了,如果不是真心对这几门语言感兴趣的黑客,谁能一眼看出来他们表示什么意思?作者所提到的认知债务,在这些「具有描述性」的名字中**依然存在**。此外,我也不太能明白为什么作者认为 Go 语言是一个有点蠢的名字,难道必须起一个像 `http-request-validator` 一样的名字,才能算好吗?那同类软件之间要如何做出区分呢?

不过,我也要承认,随便拿一个几乎毫无关联的名词做软件的名字,的确不太妥当,但我认为不妥当的点在于自我意识过剩和对作品以及用户不负责,而不是「名称不具有描述性」这个理由。比如,一个开发者很喜欢宝可梦,便把自己开发的一个系统清理工具命名为 Squirtle(杰尼龟),就不太妥当了,因为名称与工具之间几乎没有任何关联,或者说脑回路过于奇特,其他人难以建立起关联。但是,如果把一个用于将网盘挂载(mount)到文件系统中的软件命名为 Pokémount,我认为这不失为在个性和描述性之间的一种平衡(只不过这个例子可能会有版权问题,但我觉得我表达清楚我的观点了)。

作者在文中提到了一个名为 `libsodium` 的加密库,说自己看到这个名字的时候必须从「解决问题模式」切换到「一探究竟模式」,才能搞清楚这个库为什么叫这个名字——加密往往涉及到「加盐」,而名字中的 Sodium(钠)明显代指「盐」,这个名字实际上还是具有描述性的。我想说的是,开发者完全可以更专注,在解决问题的时候**收一收自己的好奇心**,就像我在用 `grep` 筛选查看返回信息的时候,只会专注找我想要的内容,而不是纠结 `grep` 这四个字母究竟是什么意思。

### 中文的「不错」和英文的「好」

> [!note] 📜
> [The Architecture of "Not Bad": Decoding the Chinese Source Code of the Void](https://suggger.substack.com/p/the-architecture-of-not-bad-decoding)

作者表示自己作为中文母语者,更喜欢用双重否定表达肯定,比如「不错」「没事」「没错」,而他观察到英文使用者更偏好直接肯定,比如「Decent」「Okay」「Right」。他认为中文使用者更偏好使用双重否定,其实是一种留白,刻意留下了一定的模糊性以避免直接承担表达的责任,设立了一种心理屏障。例如,A 在选购某种商品时寻求了 B 的建议,如果 B 说「我觉得很好」,而 A 买下之后却遇到了各种不如意,那 B 就有可能承担 A 的选择带来的后果;如果 B 说「还行吧,不坏」,没有得到直接肯定答复的 A 需要承担全部的选择带来的责任。作者认为两种语言实际上构建了两种不同的现实模型(realities)。

毋庸置疑,语言会影响思维方式,不过我并不赞同这种过于简单粗暴的二分法,实际上「Not bad」这个说法也很常见,甚至比中文里还要常见,因为中国人在相似场景下可能更喜欢说「还行」——一个语气更弱的直接肯定,而不是双重否定。

作者似乎也没有意识到,世界上说英语的人很多,全世界都有英语使用者,而作者提到的偏好肯定的、简单直白的英语,更像是美国人说的英语。文章下有一条评论是这样说的:

> 我只是过来说一句下面已经有人说过的话:你显然没有和某一类英格兰人打过交道。
>
> 美国人是喜欢玩火柴和刀片的小孩子。

<details>
	<summary>原文</summary>

> Came here to say what someone else has already said below: you've obviously had little to do with a certain sort of Englishman.
>
> Americans are children playing with matches and razor blades.

</details>

不过,作者的确在自己的认知范围内做出了足够多的分析,文章写得也足够条理清晰,读起来很有意思。只不过,这篇文章收到的一些批评也提醒我:不要陷入太过简单的二元对立陷阱中,真实情况往往更复杂;分析现象时最好要找到足够多的依据,对于这类文化问题,最好找一些英语使用者和中文使用者来讨论,或者请他们读一读文章草稿。

## ⁂ · 星群

### Atomic CSS Devtools

用于测试和 Debug 原子化 CSS 的工具,支持 TailwindCSS、UnoCSS、PandaCSS 等其他原子化 CSS 库。刚发现的时候还觉得用处不大,因为原子 CSS 的类名本身就很清晰了,但发现这个工具的同一天,我就遇到了一个奇怪的 UnoCSS 导致的问题——有一个类只有变量,但没有实际发挥作用的属性。如果没有这个 Atomic CSS Devtools,我可能要在 Styles 标签页翻找好久才能发现。

这个插件在前端开发者工具中添加了一个 Atomic CSS 标签页,会把选中元素的样式全部列出来,在右侧显示是哪个类提供了这个样式。

![](https://img.eltr.ac/uPic/2025/12/UnN7eL.png)

访问:[GitHub - astahmer/atomic-css-devtools](https://github.com/astahmer/atomic-css-devtools)

### Wails

一个跨平台的桌面端应用开发框架,后端使用 Go 语言,UI 可以使用任何前端技术构建。和 [Tauri](https://tauri.app/) 一样,Wails 不会把浏览器内核打包到最终的软件包里,而是使用系统默认 WebView,软件包的大小会比 Electron 小很多。

Tauri 使用 Rust 语言,而 Wails 使用 Go 语言,两者在前端技术上都没有限制。除了 Tauri 出现的时间比较早,生态可能更成熟之外,我认为两者都是不错的跨平台开发选择——不过相比 Electron,这两个框架在生态上都没有太大优势。

访问:[Wails](https://wails.io/)
### MrRSS

一个比较新的跨平台 RSS 阅读器,用 Wails 开发。我并没有觉得 MrRSS 的设计有多惊艳,但我对它使用的技术栈很有好感,使用的是 Go 语言和 Vue.js(~~如果用的是 Node.js 和 React 我大概会直接晕过去~~)。作者正在积极开发,如果你在选择新的 RSS 阅读器,MrRSS 可能是一个不错的选择。

访问:[GitHub - WCY-dt/MrRSS](https://github.com/WCY-dt/MrRSS)

## ↯ · 当下

### 我加入了 Fediverse

Fediverse(联邦宇宙)是去中心化的社交网络,所有使用相同协议的实例能够相互通信,使得用户可以在一个服务器上查看整个 Fediverse 中架设于其他服务器上的社交媒体实例上的内容。最常用的协议是 ActivityPub,支持这个协议的软件有 Mastodon 和 Misskey 等微博(Microblogging)平台,像 Ghost 这样的内容管理平台也有支持 ActivityPub 的,也属于联邦宇宙的一部分。

相比 Twitter(我不想用 X 这个名字)和 Instagram 这类由某个科技公司提供的社交媒体,Fediverse 更自由,用户可以选择在自己信任的服务器上注册账号(或者自己架设服务器),只需要电子邮箱就能注册,只要在任何一个支持 ActivityPub 协议的服务器上拥有账号,就能在整个 Fediverse 上和其他人交流,而且,在这里没有人想要给你推荐广告、收集和售卖你的数据。

我刚开始探索 Fediverse,所以选择了在一个公共实例上注册,未来兴许会自建实例。[@eltrac@c7.io](https://c7.io/@eltrac) 是我的 Mastodon 账号,期待能和你在联邦宇宙上相遇。

### 我加入了 IndieWeb

[indieweb.org](https://indieweb.org/) 是这样介绍自己的:

> IndieWeb 是专注于人的网络,用于替代「大公司网络」。
>
> 我们是由独立的个人网站组成的社群,基于这样的原则:拥有你自己的域名,把域名用作你最主要的线上身份,在你自己的网站上优先发表内容(发在其他地方是可选的),并且拥有你的内容。

<details>
	<summary>原文</summary>

> The IndieWeb is a people-focused alternative to the “corporate web”.
>
> We are a community of independent and personal websites based on the principles of: owning your domain and using it as your primary online identity, publishing on your own site first (optionally elsewhere), and owning your content.

</details>

之前一直很喜欢 IndieWeb 的概念,但没有深入了解。其实加入 IndieWeb 也很简单,最主要的步骤就是拥有自己的域名和网站,优先在网站上发表内容,之后再同步到其他地方,这件事情我已经在做了。要说别的什么东西,大概就是设置一下 Microformats、配置 IndieAuth 和支持 Webmention。

Microformats 是基于 HTML 的一种标记内容和身份的格式,主要用来帮助自动化工具展示作者信息和内容信息,详情可查阅 [IndieWeb Wiki](https://indieweb.org/microformats)。

至于 IndieAuth,就是给链接加上 `rel="me"` 属性以声明链接到的个人资料的确属于自己,这个链接可以是 `<link>` 也可以是 `<a>`,以下是我的写法:

```html
<link rel="me" href="https://c7.io/@eltrac">
<link rel="me" href="https://github.com/BigCoke233" />
<link rel="me" href="mailto:hi@eltr.ac" />
```

确保网站上有 `rel="me"` 的内容之后,还需要在以上链接中链接到自己的网站,比如在 GitHub 个人资料中设置个人主页链接。许多 IndieWeb 相关的服务,比如 [webmention.io](https://webmention.io/),支持 Web Sign-In,只要提前配置好了 IndieAuth,就可以通过自己指定的 GitHub 账号或电子邮箱等方式,以域名拥有者的身份登录。

如果你拉到网页最下方,会发现博客的评论按钮旁边多了一个图标为 `@` 的按钮,这就是 Webmention,一个 W3C 标准。你可以以发送 HTTP 请求的方式向支持 Webmention 的网站发送回复、点赞、提及等回应,自己也可以作为接收方接收这种回应,展示在网页上。只要配置得当,在自己的网站中插入链接就能像在社交媒体上用 `@用户名` 的形式提及其他用户一样给其他人发送通知,不过要完全自动化还是有些麻烦的。

我使用 [webmention.io](https://webmention.io/) 提供的服务来接收 Webmention,在 `<head>` 中添加了以下代码来声明我的 Webmention 端口。

```html
<link rel="webmention" href="https://webmention.io/www.geedea.pro/webmention" />
```

向这个端口发送 Webmention,就会展示在我的网站上。你可以点开博客下方的 Webmention 按钮,查看这一页收到的 Webmention,也可以通过表单提交你的网址以手动发送 Webmention,不过发送 Webmention 的前提是你提交的网址中有链接到这个页面。[^4]

我目前还没有配置自动发送 Webmention,用静态网站生成器还是不太方便做自动化,要自己配置 GitHub Actions,兴许有空了我会尝试一下。

在发布周刊之前我就收到了两个 Mentions,有些惊喜,如果你不喜欢发评论,或者没有 GitHub 账号,可以在自己的网站上撰写一篇文章回应我,又或者只是在写文的时候简单提及,无论怎样我都会很开心的。

[^1]: 参见:[康塔塔 - 维基百科](https://zh.wikipedia.org/wiki/%E5%BA%B7%E5%A1%94%E5%A1%94)

[^2]: 原名:Schweigt stille, plaudert nicht (Be still, stop chattering), BWV 211,也叫 Coffee Cantata

[^3]: 歌词来源:[EMMANUEL MUSIC](https://www.emmanuelmusic.org/bach-translations/bwv-211)

[^4]: 经过测试,我发现在社交媒体上发布链接并提交 Webmention 并不能成功推送通知,因为发送 Webmention 的前提是源链接(也就是你提交的链接)指向的网页中,有链接到目标链接(也就是你要发送 Webmention 的网页)的超链接。社交媒体的内容一般是通过 JavaScript 动态展示的,HTML 中没有内容,所以也就检测不到链接。