跳到內容
關於我 數位花園

部落格

遞迴函式與夢境

遞迴函式是一個很有趣的東西

也常在一些特殊的資料結構上會使用到

而遞迴最主要的構成因素就是在函式裡面呼叫自己,大概長得像是下面的結構:

function recursion(param) {
recursion(param);
}
// initial call
recursion(initialParam);

但若像上面的結構,不斷地呼叫自己,沒有終止的機制,就會像無窮迴圈一樣,讓電腦記憶體爆掉

因此,遞迴函式裡面必須有一個刹車的機制

流程控制:繼續走?還是回頭?

Section titled “流程控制:繼續走?還是回頭?”

在流程控制(control flow)上,可以分成兩條路:

  • 符合終止條件:停止
  • 不符合終止條件:呼叫自己

流程圖大概如下:

graph LR
A(Initial call) --> B{Continue?}
B -->|No| C(Finish)
B -->|Yes| D(Call again)
D --> E{Continue?}
E -->|No| F(Finish)
E -->|Yes| H(Call again)
H --> I(Go on...)

我很喜歡用一個比喻去詮釋遞迴的概念,那就是:全面啟動

電影中的主角柯伯如何進入夢境的?

沒錯,睡著就行了!

而在夢中的他,有兩個選擇:

  1. 醒來,回到現實世界
  2. 再睡著一次,進入「夢中夢」,也就是第二層夢境

但不幸的是,隊員的其中一人在出任務的時候受傷而進入昏迷狀態,柯伯必須去下一層救他

原本計畫順利的話,應該就此打道回府才是

然而面對這樣情況,他也無法執行了

任務達成的條件尚未成立

於是他說:「我們必須前往更深處」

go deeper

他只好再睡著一次,去下一層夢境了

然後他終於找回隊員了

該怎麼回到現實世界呢?

沒錯!就是 kick!

would be a kick

在理解遞迴的同時,也需要先了解這兩個關鍵字作為基礎知識

一個是執行環境(execution context),另一個則是堆疊(stack)

這裡就直接用英文稱呼,比較直覺一點

在 JavaScript 的世界裡,其實有兩種 execution context:

  • 全域執行環境(Global Execution Context)
  • 函式執行環境(Function Execution Context)

而我們這裡討論的,主要是函式執行環境,而所有函式執行環境的最外面,即是所謂的全域執行環境

context 就是記住當下的時空背景:當下的有哪些變數、其值又是什麼

每一次的函式呼叫,就會創造一個新的 context,以便記憶此次呼叫的環境狀態

創造出來 context 則會存放在稱為 stack 的地方

新的 context 建立了之後,就丟進去這個 stack,

因此,stack 裡的順序就會是:舊的在下,新的在上

下一次要去拿 context 的時候,就會先拿到比較新的 context

大致了解 context 與 stack 的概念之後,我們來看一個簡單的範例:階乘的計算

同時,我們把全面啟動的故事也放在手邊(到底是有多愛全面啟動

階乘的數學定義如下:

$$ n! = n \times (n - 1) \times (n - 2) \times \ldots \times 3 \times 2 \times 1 $$

我們要拿指定的初始值 n 去做階乘計算

function factorial(n) {
// 終止條件
if (n === 0) {
return 1;
} else {
return n * factorial(n - 1); // 呼叫自己
}
}
factorial(4); // result: 24
factorial(2); // result: 2
factorial(0); // result: 1

終止條件是,當 n = 0 時,return 1

因為階乘的定義上:

$$ 0! = 1 $$

假設我們的初始值 n = 3,於是我們執行第一次的呼叫:

factorial(3);

柯伯坐在飛機頭等艙舒適的座椅上睡著了,進入了夢境

第一次的呼叫,建立的一個新的 context,裡面有我們帶進去的 n = 3

所以我們可以這樣表示:

Context { n: 3 }

並且將這個 context 丟進 stack 中儲存,可以這樣表示:

Stack = [
{ n: 3 }
];

然而我們的 n 沒有符合終止條件,於是,進行了第二次的呼叫 factorial

柯伯為了解任務,再次睡著進入了夢中夢

此時,我們帶入 factorial 的參數是 n - 1,所以是 3 - 1 = 2,帶入 2

第二次的呼叫,再次建立一個屬於它的 context:

Context { n: 2 }

於是 stack 變成:

Stack = [
{ n: 2 },
{ n: 3 }
];

我們又回到了函式的第二行,再次判斷終止與否,但仍未滿足條件,於是進行第三次的呼叫:

柯伯達成任務了,不料,隊員昏迷不醒,於是他躍身進入下一層夢境

然後再重複了一次遞迴

OK,這次 n = 0,所以要 return 1 回去,至此,不再遞迴下去

柯伯找回遺失的隊員要打道回府了

return 代表結束這個函式,並回傳值

但別忘了,我們現在在第幾層夢境?

柯伯說:「我是誰?我為什麼在這裡?」

啊,我是指在哪一個 context 裡?

最後那一個對吧,也就是 stack 最上面那個:Context: { n: 0 }

所以當我們 return 之後,回到上一次層是:Context: { n: 1 } 這個 context,而不是現實世界(aka Global 的 context)

柯伯醒來一次,回到上一層夢境

然後我們看到上一層這樣寫:return n * factorial(n - 1)

於是,1 跟上一層的 n 相乘之後,又繼續 return 更上一層,一連串的 return

柯伯一行人,藉由一連串的 kick,一路回到現實世界

整個過程像是這樣:

factorial(3);
3 * factorial(2);
2 * factorial(1);
1 * factorial(0);
return 1;
return 1 * 1;
return 2 * 1;
return 3 * 2;

於是最後我們得到結果就是:

$$ 3! = 6 $$

我們總共呼叫了 factorial 這個函式四次,稱之為遞迴的深度(depth)

如果我們想知道每一次呼叫時的 depth,可以這樣寫:

function factorial(n, depth) {
console.log("depth: ", depth); // 現在的遞迴深度
console.log("context: n =", n); // 當前的 n 值,也就是目前的 context
if (n === 0) {
return 1;
} else {
return n * factorial(n - 1, depth + 1);
}
}
factorial(2, 1); // 第一次呼叫,所以深度從 1 開始

這樣就可以看到每一個 context 及對應的 depth 了:

depth: 1
context: n = 2
depth: 2
context: n = 1
depth: 3
context: n = 0

於是柯伯轉動手上的陀螺,以避免迷失自我

而這裡的 console.log 則成為各個 context 裡的指標(電影裡稱之為「圖騰」totem)

spinner

但柯伯的陀螺只能判斷是在夢境(aka Function Execution Context)或是現實(aka Global Execution Context

還是不太方便呢(重點錯

由上述的範例可知,每一次的呼叫,就會創造一個 context 並存到 stack 之中

所以遞迴的深度越深,context 也會越多,電腦需要花更多的記憶體去存放這個龐大的 stack

到達極限的時候,就會造成「堆疊溢位」(stack overflow)

遞迴函式自有它簡潔優雅的優點,但優點是用吃重記憶體這個缺點換來的

就像我們以前會說:「Chrome 瀏覽器的速度好快啊!」但它是吃記憶體的大怪獸啊

基於效能的考量,就會衍生出迭代(Iterate)與遞迴(Recursion)的優缺點比較了

有機會再聊這塊

其實一直想要寫關於遞迴的文章

但又不知道從何寫起

而每當在用遞迴函式的時候,總想到全面啟動這部電影

為了寫這篇,我還重新看了一次電影呢 🙈

參考網路上很多關於遞迴的範例

其他常見的遞迴範例還有,像是費式數列、巴斯卡三角、巢狀資料結構的處理……等

他們都寫得很好,我也把連結列在參考資料

或許我並不是想要寫遞迴,而是全面啟動吧 🙃

[小說] 便利店人間 - 我們都是組成世界的小齒輪

book cover

博客來-便利店人間

惠子在便利店打工,已經過了 18 年了

從這間便利店開店以來,換了好幾任店長、當初的同事們都已經不在這裡了

只有惠子,是這裡唯一不變的因素

提示:以下有劇透,請自行斟酌


從小的時候,她就是個古怪的孩子

一些言語或是舉動,時常換來大人們的驚訝或無語

甚至她的家人們也不斷地在討論該如何治好

或許,跟其他人不一樣,就顯得不太正常,而是異常,是故障的,必須修理才行

然而,她還是不懂自己到底哪裏故障了,哪裏又需要修理

隨著年紀的增長雖然沒有解決她的疑惑

倒是讓她學會一件事:

只要看起來像是普通人,就不會讓家人擔心了

大學的時候開始在這間便利店打工的時候,家人們都很高興

對惠子而言,她不懂怎麼做才能成為普通人

自從進入便利店打工以來,各式各樣的人來這裡,

當大家穿上便利店店員的制服、照著員工手冊去收錢、補貨、各種店內雜務

就宛如變身成稱為「便利店店員」的生物

只要穿上制服、依循員工手冊去行動,就好像變成了普通人一樣

曾經一任店長對她說:

時薪裡面也包括做好自我管理,帶著健康的身體去上班 1

也就是說,健康管理,也是對工作的很重要的一環

於是,她的整個生活,都是以便利店為中心著想的

然而,整整 18 個年頭都在便利店打工,又讓家人、朋友感到疑惑

大學的幾個時常相聚的同學幾乎都結婚或是生了小孩

而她今年 36 歲,還是一個單身打工族

這樣的標簽難免不引起別人的好奇

她跟多年保持聯絡的同學們聚餐

聚餐上,結婚的同學們帶來她們的老公

也理所當然地分享彼此的近況

然而,惠子卻因此成了焦點

雖然借用了妹妹建議她的說詞:

因為身體不好,所以在便利店打工

還是無法制止大家的好奇心,尤其是那些初次見面的同學的老公

大家突然像是記者似地詢問,或該說是審問

接二連三的身家調查,開始出主意

本人並未尋求建議,大家已經開始幫她想好人生的劇本、下一步該怎麼做、有沒有對象可以介紹 ⋯⋯ 等等

在這樣光景,讓她回想起小學的時候:

眾人都有些疏遠我,把身子轉開,眼睛卻帶著好奇,就像觀察某種可怕生物似地望著這裡

於是她想著:「啊,我變成異物了

某日,新來的打工男子,叫做白羽

他是一個很厭世、工作不認真、還會騷擾女客人、女同事的人

店裡的人都很討厭他

不到兩週的時間就被火了

某日惠子撞見他又要跟蹤女客人

為了避免她又去騷擾別人

所以將他拉去家庭餐廳,開始聽他悲憤地發表言論:

世界無法容忍異物,大家都被要求叫不要一致

年紀大還在打工會被質疑、為何沒有戀愛經驗

現代其實還是像遠古時代的部落

無法參加打獵或是對部落沒什麼貢獻的人,都會被部落的人瞧不起

然後成為部落的累贅

⋯⋯⋯⋯

於是,無業的他,為了不被世界排擠

想要透過結婚,隱身在這個社會當中

藉此貼上稱為「普通人」的標籤

於是惠子提出了結婚的提議 ⋯⋯

雖然最後結婚這件事不了了之

但惠子收留了因為沒繳房租被趕出來、居無定所的白羽

從外界看來,他們成了同居人

但也只是同時存在在便宜小公寓的兩人

白羽藏匿在此,可以躲避外界的眼光

一開始雖然不太情願,但後來也認為這個提議不賴

而惠子打電話跟妹妹只說了一句:「有男人在我家裡」

引來了妹妹自行腦補了很多情節,而且很為她高興

此時,她成了正常人

惠子也因此免除了一些煩惱

因為在短短近兩週的期間,被問了「為何還沒結婚?」14 次、「為何還在打工?」12 次

繼上次打電話給妹妹之後,惠子又在大學同學的聚會做了一次試探

然後她們興高采烈地自行腦補了一個劇本

就算對她們來說,是一個除了名字之外、完全素未謀面的陌生人

她感受到自己好像真正加入了她們的圈子

不禁感嘆:原來我一直以來都是圈外人

某天,惠子辭去了做 18 年的便利店打工

大家都以為是白羽有工作了,很高興地歡送她離開

而事實上卻相反

那個無所事事的男人很認真得逛著求職網站

但卻不是自己要去面試,而是要惠子養她

從便利店離職之後,她的整個作息就變得亂七八糟

吃飯也是有一餐沒一餐的

起床時都不知道是現在是幾點

因為沒有要去便利店工作,所以開始失去生活目標

變得渾渾噩噩

某日,終於收到了一家公司的面試通知

白羽則跟著她一起前往面試地點

在面試前,她們路過一間便利店借用廁所

惠子感受著便利店的各種聲音、架上的商品、不熟稔的新進店員 ⋯⋯

她順手幫忙整理商品,引來新店員的稱讚

此時的她,終於想通了一件事

她終究是稱為「便利店店員」的一種生物

便利店的「聲音」不停地流入我的體內,我是為了聆聽這聲音而生的 2

她知道自己接下來不該去面試的

我醒悟了。我不僅僅是個人,更是個便利店店員。 即便我是一個扭曲的人,即便養不活自己而路倒街頭, 我還是無法逃離這個事實。 我所有的細胞都是為了便利店而存在的。3

白羽很氣憤地離開了

於是兩人從此分道揚鑣

而惠子心裡想著:

得趕快調養好身體,以便快速地行動、更迅速地補充飲料、拖好地板、更完美地聽從便利店的聲音 4

於是,接下來要開始準備應徵新的便利店工作了

我不經意地望向倒映在剛離開便利店玻璃上的自己。 一想到這雙手、這雙腳,全是為了便利店而存在, 我覺得倒影中的自己頭一次成了一個有意義的生物 5

故事就到這邊為止了

相信往後的幾年,她還是會繼續在便利店工作吧

書中不斷地描述社會上大部分人的想法及他們看待怪人的反應

大夥每天埋頭苦幹的目的,就是為了跟上群體的腳步

照著一樣的劇本,演一樣的戲碼

或者說,依照工廠的生產手冊,製作出一樣的產品

就如白羽所說:「對部落沒有貢獻的人,就會被視為異類、被唾棄、或等著被淘汰

日本的社會群體意識之高,是眾所皆知的

也在本書中,用不同對話不斷印證這一點

或許隨著時間推移,現在也有所改變也說不定

而在漫長的人生當中,我們又到底在追求什麼

又是為了什麼而活著呢?

或許惠子會在往後的日子裡,再次遇到同樣的事情

接受各種質疑、議論紛紛、狐疑的眼光對待

在她之後的人生裡,究竟還會發生什麼樣的事呢?

她還能在便利店工作多少年、老年又會過著怎樣的生活?

作者並沒有提到

說不定就如她自己所說的:養不活自己而路倒街頭

我還真不忍想像。。

小說人物的幸福 6 在於:不用擔心接下來會發生什麼事

因為故事結束了,然後就沒有然後

然而值得高興的是,她終於找到了屬於她的地方

而且是可以奉獻她整個人生的地方

大概就就如同白羽所謂的「為村落帶來貢獻」吧

這樣說起來,也不是什麼壞事吧

這本書沒有很長,很快的就看完了

然而因為要加入故事的節錄,而翻覆翻閱其中比較重要的對話與劇情

所以花了額外一些時間

甚至也看了日文版的內容

白羽用日文說話的時候,聽起來倒是滿客氣的,不像中文那樣不屑

整個人的印象不太一樣

無業厭世男的角色印象沒有變就是了

另一點值得一提的就是

每看一次其中的對話時,就有一種莫名的沈重感

像是那種潮濕悶熱的空氣般,使呼吸有點不太順暢的那種沈重感

時常為深陷困境或尷尬場面的惠子捏一把冷汗

但又想不出更好的方式為她解圍

也因此讓我低落了一陣子

反倒是她本人雖然感到困擾,但也表現出怡然自得的樣子

或許她本來就是這樣我行我素的人吧

  1. 原文:体調管理をして健康な体をお店に持っていくことも時給の内だ

  2. 原文:身体の中にコンビニの『声』が流れてきて、止まらないんです。私はこの声を聴くために生まれてきたんです。

  3. 原文:気がついたんです。私は人間である以上にコンビニ店員なんです。人間としていびつでも、たとえ食べていけなくてのたれ死んでも、そのことから逃れないんです。私の細胞全部が、コンビニのために存在しているんです。

  4. 原文:コンビニのために、また身体を整えないといけない。もっと早く正確に動かして、ドリンクの補充も床の掃除ももっと早くできるように、コンビニの『声』にもっと完璧に従えるように、肉体のすべてを改造しかなくてはいけないのだ。

  5. 原文:私はふと、さっき出てきたコンビニの窓ガラスに映る自分の姿を眺めた。この手も足も、コンビニのため存在していると思うと、ガラスの中の自分が、初めて、意味のある生き物に思えた。

  6. 該說是幸福,還是不幸呢?

重訓名詞中英日對照(持續更新)

鑒於前陣子看了「流汗吧!健身少女」這部動畫,再加上去健身房做訓練, 開始認識一些健身相關的名詞, 所以想要整理出中、英、日三國語言的名詞對照表, 如果有錯誤還麻煩不吝指教 🙏

中文English日本語
自身自重訓練Bodyweight Training自重(じじゅう)トレーニング
器械重量訓練Machines Trainingマシントレニング
自由重量訓練Free Weightsフリーウエイト
體幹訓練体幹(たいかん)トレーニング
彈力帶訓練チューブトレーニング
バランスボール(きん)トレ
中文English日本語
槓鈴臥推Bench Pressベンチプレス
啞鈴臥推Dumbbell Pressダンベルプレス
啞鈴飛鳥Dumbbell Flyダンベルフライ
啞鈴彎舉Dumbbell Curlダンベルカール
啞鈴錘式彎舉Hammer Curlハンマーカール
傾斜啞鈴彎舉Incline Dumbbell Curl
佐特曼彎舉Zottman Curl
啞鈴斜托彎舉Decline Dumbbell Curl
W 型彎曲槓彎舉EZ Bar Curl
Kick Backキックバック
法式彎舉
仰卧臂屈伸
頭顱粉碎者
French Pressフレンチプレス
Front Pressフロントレイズ
Side Pressサイドレイズ
Dumbbell Rear Raiseダンベルリアレイズ
硬舉Dead Liftデッドリフト
捲腹Crunchクランチ
Abs Rollerアブローラー
深蹲Squatスクワット
中文English日本語
紅肌
慢縮肌
Red Muscle
Slow Twitch
遅筋(ちきん)(持久筋(じきゅうきん)・SO 筋・赤筋(せっきん))
白肌
快縮肌
White Muscle
Fast Twitch
速筋(そっきん)(短瞬発筋・FG 筋・白筋(はっきん))
速筋(そっきん)(長瞬発筋・FO 筋・ピンク(きん))
中文English日本語拉丁語
胸大肌pectoralis major大胸筋(だいきょうきん)musculus pectoralis major
胸小肌pectoralis minor小胸筋(しょうきょうきん)musculus pectoralis minor
前鋸肌Serratus anterior前鋸筋(ぜんきょきん)
ボクサー(きん)
musculus serratus anterior, serratus lateralis
背闊肌Latissimus dorsi muscle広背筋(こうはいきん)musculus latissimus dorsi
斜方肌Trapezius僧帽筋(そうぼうきん)musculus trapezius
三角肌Deltoid muscle三角筋(さんかくきん)Musculus deltoideus
回旋筋腱板
ローテーターカフ
肱二頭肌biceps brachii muscle上腕二頭筋(じょうわんにとうきん)musculus biceps brachii
肱肌Brachialis muscle上腕筋(じょうわんきん)musculus brachialis
肱三頭肌Triceps brachii muscle上腕三頭筋(じょうわんさんとうきん)Musculus triceps brachii
muscles of the forearm前腕筋群(ぜんわんきんぐん)musculi antebrachii
腹直肌Rectus abdominis muscle腹直筋(ふくちょくきん)musculus rectus abdominis
腹外斜肌Abdominal external oblique muscle外腹斜筋(がいふくしゃきん)musculus obliquus externus abdominis
腹內斜肌Abdominal internal oblique muscle内腹斜筋(ないふくしゃきん)musculus obliquus internus abdominis
Transversus abdominis muscle腹横筋(ふくおうきん)musculus transversus abdominis
長背筋群
Iliopsoas muscle腸腰筋(ちょうようきん)musculus iliopsoas
股四頭肌quadriceps femoris muscles大腿四頭筋(だいたいしとうきん)musculus quadriceps femoris
大腿後肌Hamstring大腿屈筋群
ハムストリングス
Triceps surae muscle下腿三頭筋(かたいさんとうきん)musculus triceps surae
中文English日本語
跑步機Treadmillトレッドミル
ランニングマシン
スピンバイク
滑步機
橢圓機
Ellipticals
飛輪Stationary bike
划船機Rowing machineローイングマシン
胸推機Chest Pressチェストプレス
蝴蝶機Butterfly Machineバタフライマシン
器械肩推Machine Shoulder Pressマシンショルダープレス
滑輪下拉Lat pulldownラットプルダウン
ラットマシン
坐姿划船Seated Rowingシーテッドローイング
Back Extensionバックエクステンション
Abdominal Crunchアブドミナルクランチ
Cable Crunchケーブルクランチ
大腿推蹬機Leg pressレッグプレス
雙腿伸屈Leg Extensionレッグエクステンション
坐姿腿部外彎機Hip Abductionヒップアブダクション
マルチヒップアブダクション
引體向上Pull-up
中文English日本語
啞鈴Dumbbellダンベル
槓鈴Barbellバーベル
懸垂マシン
チンニングマシン
長凳Benchベンチ
彈力帶Stretch Strapチューブ
ゴム
プッシュアップバー
バランスボール
腹筋ローラー
アブローラー
壺鈴Kettlebellケトルベル
ハンドグリップ
メディシンボール
アブマット

html ruby 標籤與亞洲語系標音

因為想要在 markdown 上面寫日文,希望在漢字上面標上假名,所以來研究一下如何實作

查了一下,發現了平常很少用到的 <ruby> 標籤

根據 MDN 的文件:

HTML <ruby> 元素的意思是旁註標記。旁註標記用於標示東亞文字的發音。

包在 <ruby> 標籤內的字,就可以加上標音,以日文為例:

とある<ruby><rb></rb><rt></rt><rb></rb><rt>じゅつ</rt></ruby><ruby><rb>禁書目録</rb><rt>インデックス</rt></ruby>
とある<ruby><rb></rb><rt></rt><rb></rb><rt>がく</rt></ruby><ruby><rb>超電磁砲</rb><rt>レールガン</rt></ruby>

渲染出來的結果:


とあるじゅつ禁書目録インデックス

とあるがく超電磁砲レールガン


<ruby> 裡面包含兩種元素:<rb><rt>

rb 是 ruby base 的意思,也就是要被標音的文字,像是日文漢字或中文字

rt 是 ruby text,也就是標音文字,像是平假名、片假名、注音等

一個 <rb>,後面接的 <rt> 就會標註在前面的 <rb> 上面

當然,中文的注音也可以:

<ruby><rb></rb><rt>ㄅㄧㄢˋ</rt><rb></rb><rt>ㄊㄞˋ</rt></ruby>
<ruby><rb></rb><rt>ㄐ一ㄢˋ</rt><rb></rb><rt>ㄆㄢˊ</rt><rb></rb><rt>ㄗㄨㄟˇ</rt><rb></rb><rb></rb><rt>ㄆㄠˋ</rt></ruby>

結果:


ㄅㄧㄢ ˋㄊㄞ ˋ

ㄐ一ㄢ ˋㄆㄢ ˊㄗㄨㄟ ˇㄆㄠ ˋ


也來試試韓文:1

<ruby><rb></rb><rt>저우쯔위</rt><rb>子瑜</rb><rt>조쯔위</rt></ruby>

結果:


저우쯔위子瑜조쯔위


我們可以把整段要標音的文字都放在 <ruby> 裡面,也可以以詞彙為單位分段:

<ruby><rb></rb><rt></rt><rb></rb><rt>ばく</rt></ruby>
<ruby><rb></rb><rt>もく</rt><rb></rb><rt></rt></ruby>
<ruby><rb></rb><rt>ろく</rt></ruby>
カイジ

結果:


ばく もく ろく カイジ


基本上沒有特別規定,如何整理依個人喜好而異

Hugo 支援直接在 markdown 寫 html,所以上面的那些範例都可以正常地被渲染出來。但問題是寫法不友善,也不好閱讀

然後在網路上找到一位日本人 Spiegel 分享了一段關於 ruby 的 shortcode 之後,就新增進我的 shortcode 裡面:

layouts/shortcodes/ruby.html

<ruby><rb>{{ .Inner }}</rb><rp>(</rp><rt>{{ index .Params 0 }}</rt><rp>)</rp></ruby>

原本我們要這樣寫:

<ruby><rb>再起不能</rb><rt>リタイヤ</rt></ruby>

往後可以這樣寫:

{{</*ruby "リタイヤ">}}再起不能{{</ruby */>}}

結果:


再起不能(リタイヤ)


只需要寫最外層的 <ruby> ,而不用寫裡面的 <rb><rt> 了~

但用這個 shortcode 的寫法,就變成以一個 <ruby> 為標音單位了:

とある{{</*ruby "ま">}}魔{{</>}}{{<ruby "じゅつ">}}術{{</ruby>}}の{{<ruby "インデックス">}}禁書目録{{</ruby */>}}

結果:


とある()(じゅつ)禁書目録(インデックス)


科技始終來自於惰性啊 😎

在 google 的時候,其實不太好搜尋,一方面資料本來就少,另一方面,跟 ruby 語言同名的關係,非常容易查到 ruby 語言的相關資訊 😂

標音功能在我網頁開發近兩年的時間裡(菜逼八),完全沒有用到過,多國語言就算有日文,八成不會有標音吧。如果我是在出版社或教育界工作的話,那還比較有可能呢

  1. 我不懂韓文,所以這是參考子瑜的維基百科,若有標音斷句錯誤再麻煩糾正我,謝謝 🙏

[開箱] Nomad 無線充電盤與皮革錶帶

觀望 Nomad 這個品牌有一陣子了,很喜歡他們低調沉穩的色調及產品設計。尤其是對無線充電盤 Base Station 系列與 Apple Watch 皮革錶帶特別有興趣

考慮買無線充電盤卻遲遲沒有入手,是因爲手邊支援無線充電的裝置,只有 iPhone 與 AirPods Pro,因此覺得沒有改成無線充電的絕對必要性。直到前陣子入手了 Apple Watch 之後,就有購買花錢的理由,三個裝置都支援了無線充電,實現了所謂的三位一體方便且可同時為所有裝置充電的方案

Nomad 的無線充電盤大概分爲以下幾種:Base Station Pro、Base Station、Base Station Stand、Base Station Mini

Base Station Pro 要價 US$199.95(約 NT$5,516),是尊爵不凡的最高級款。最大特色就是「全表面充電」(Full-Surface Charging),有別於一般的無線充電必須對準線圈的中心才能充電的小缺點,它的黑科技(官方稱為 FreePower 演算法)可以自動判斷手機的位置並進行充電,最多可支援三個裝置隨手丟在充電盤上充電,某方面是實現了蘋果公司當時沒有上市的 AirPower 無線充電盤

Base Station 就是一般的無線充電盤,擁有三個充電線圈,最多同時為兩個裝置充電。有三種版本:Hub 版、Watch 版、Watch Mount 版。後面兩者的差異在於後者只有手錶架,必須加裝 Apple Watch 的磁吸充電器才行;前者則有内附 MFI 原廠認證的磁吸充電器

此款是直立式無線充電盤,價格 US$99.95(約 NT$2,756),只能為一支 iPhone 充電。此外,直立式的充電盤不在我的考慮範圍内,所以這裡就不做太多介紹了

同樣也是單一裝置的無線充電盤,可以算是 Nomad 入門無線充電盤了,價格 US$69.95(約 NT$1,929)。體積小巧,如果沒有太多充電設備的話,這款也滿不錯的選擇。也因爲功率較低,所以只需要 20W 的變壓器就可以驅動。擁有磁吸功能,只要是 iPhone 12 以後的機種,放上去就可以輕鬆地對應到可以充電的位置

美國官網的整新品:價格很香,但看得到買不到

Section titled “美國官網的整新品:價格很香,但看得到買不到”

去年(2021 年)11 月錯過了黑色星期五(Black Friday)官網的大折扣活動。想説聖誕節應該還有優惠活動吧?但什麽都沒有……

某天看到了官網的 Outlet Sales 上架了 Base Station 的整新機,價格最多有到原價的 5 折!當下看了很心動,很開心地加入購物車,要填寫國際寄送的時候就卡住了……上面顯示無法運送至該地址。我試了一下一般的產品是可以運送到台灣的。於是推測應該是整新機不給送海外。想花錢卻買不到啊~

直到聖誕節的隔日,12/26 看到全站 8 折的活動:Treat Your Self ⋯⋯ 😭

嗯?你說這表情?這叫做內牛 ⋯⋯ 啊不是,是淚流滿面

原本有考慮 Base Station Apple Watch Edition,但因為已經有原廠附的磁吸充電器了,若買了 Apple Watch Edition,充電器就會晾在一旁,覺得這樣有點浪費。所以最後買的是磁吸版本的 Base Station Hub Station | Magnetic 搭配 Apple Watch Charging Mount

base station box

因為最新的磁吸版本目前只有 Hub 版,所以要加手錶架,再裝上去:

watch mount box

其實是用 3M 膠黏上去的,有安裝說明書、適應各種尺寸手錶的橡膠墊片:

watch mount content

充電盤後面還有兩個充電孔,依序是 USB-A、USB-C、電源孔、光源感應器:

base station back

另外還有附兩個國際插頭可以替換,一個歐規(右)、一個英規(左):

base station plug

Nomad 目前的錶帶材質,分成皮革、橡膠與金屬(鈦金屬與不鏽鋼)

但說到 Nomad,第一個聯想到的材質當然是皮革啦

以往都習慣配戴橡膠的錶帶,基於防水及耐用性的考量,但一直有想要嘗試皮革錶帶的想法

Nomad 的 Modern BandTraditional Band 皮革錶帶看起來都不錯,後來選擇了 Modern Band,我選的是棕色、黑色錶扣:

leather band

發現皮革材質不太防水,洗手的時候難免會有噴濺到皮革的表面,皮革就會有很明顯的痕跡,乾燥之後,痕跡才會慢慢消失,對於用習慣橡膠錶帶,洗手時有時候會順便沖洗手錶的我來說,算是有點小不習慣。如果要防水又想要皮革錶帶的話,就要選擇 Active Band Pro 皮革橡膠複合材質的錶帶了,但是就少了皮革的味道

另外,皮革錶帶是用幾次後,就會有明顯的皺紋,尤其是內側:

leather band front

leather band back

防水的部分,目前簡單用皮革保養油做簡單防水,未來考慮用防水噴霧做防水塗層,彌補原本不防水的皮革表面

Nomad 錶帶用的皮革就是 Horween 的皮革,對皮革沒什麼太多研究的我,不禁好奇:Horween 皮革又是何方神聖?

查了一下別人的介紹文章,發現這家發跡於美國芝加哥的皮革公司,他們生產的皮革被用在很多知名品牌上,例如:Alden、Timberland、Cole Haan、Carmina、Allen Edmonds、Chippewa⋯⋯ 等,無論是平價或是昂貴的品牌,聽起來就滿厲害。(雖然我只聽過 Timberland 🙈)此外,美國三大運動聯盟:NFL(美式足球)、NBA(籃球)、MLB(棒球)都使用 Horween 皮革製作比賽用具,像是 Wilson 的美式足球、Spalding 的籃球、Rawlings 的棒球手套

用手機多年來都是使用有線的方式充電,不但穩定快速、發熱量低也對電池比較的壽命。但如果很多裝置每天都要頻繁地充電,充電的便利性就相對重要,因此才決定改用無線的方式。至於電池壽命嘛 ⋯⋯ 我用手機平均是 2 ~ 3 年,而且從未換過電池(全部有線充電的情況)就換新手機了,若真的感受到電池嚴重老化,就送原廠換一顆新電池吧!畢竟為了極度保護電池健康而無法隨心所欲地充電,對我而言只是本末倒置罷了,花錢買來的東西就是要開心地使用,為生活帶來價值,而不是用得提心吊膽,各位同學認為呢?