en
Feedback
ToCode

ToCode

Open in Telegram

טיפים ×§×¦×Ø×™× ×œ×ž×Ŗ×›× ×Ŗ×™× ×ž××Ŗ ינון פרק

Show more
1 420
Subscribers
No data24 hours
No data7 days
-530 days
Posts Archive
ToCode
1 420
שלוש תחנות ×‘×“×Ø×š ×œ×ž×¦×™××Ŗ עבודה בהייטק קודם כל גילוי נאות, בתור ×¤×Ø×™×œ×× ×”×Ø ב 12 שנים האחרונות עבר הרבה זמן מאז הפעם האחרונה שחיפשתי עבודה. אני היום ×ž×›×™×Ø את העולם הזה יותר ×“×Ø×š ×—×‘×Ø×™× או ×ž× ×™×”×™×•× ×•×Ŗ שלי ×œ×¢×–×•×Ø ×œ×œ×§×•×—×•×Ŗ לגייה. ובכל זאת ×ž× ×§×•×“×Ŗ המבט הקצת ×ž×Ø×•×—×§×Ŗ שלי יש שלושה עקרונות ××•× ×™×‘×Ø×”×œ×™×™× שאני רואה בכל ×Ŗ×”×œ×™×š של חיפוש או גיוה. עקרונות ×©×›×©××Ŗ× מבינים ××•×Ŗ× ×”×Ŗ×ž×•× ×” של חיפוש עבודה נראית הרבה פחות מלחיצה. בניית תשתית ×”×¢×™×§×Ø×•×Ÿ ×”×Ø××©×•×Ÿ הוא בניית התשתית. תשתית במובן של חיפוש עבודה ×ž×•×Ø×›×‘×Ŗ ×ž×”×™×›×Ø×•×Ŗ עם אנשים ×Ø×œ×•×•× ×˜×™× ×‘×Ŗ×—×•×, שיפור ×”×Ø×ž×” ×”×ž×§×¦×•×¢×™×Ŗ שלכם, בניית ×Ŗ×™×§ עבודות ×©×ž×Ø××” על ×™×›×•×œ×Ŗ ×ž×§×¦×•×¢×™×Ŗ ובניית ×ž×™×•×ž× ×•×™×•×Ŗ רכות שיאפשרו לכם ×œ×”×©×Ŗ×œ×‘ ×‘××Ø×’×•×Ÿ. ×”×¤×Ø×˜×™× כאן הם פחות חשובים וקל למצוא המון טיפים ברשת לזה. בגדול בשביל ×œ×”×›×™×Ø אנשים כדאי לשלוח קורות חיים ×œ×—×‘×Ø×•×Ŗ השמה ולצלצל ×œ×ž×’×™×™×”×•×Ŗ שם כדי להבין מה כדאי לשפר (וכך ×œ×”×Ŗ×™×™×“×“ עם ××•×Ŗ× אנשים בחברות ההשמה), ×œ×”×©×Ŗ×Ŗ×£ ×‘××™×Ø×•×¢×™× מקצועיים של התעשייה, ×œ×œ×›×Ŗ ×œ×”××§×Ŗ×•× ×™×, להיכנה ×œ×§×”×™×œ×•×Ŗ ברשת ×•×œ×”×©×Ŗ×Ŗ×£ בדיונים שם. כל דבר שעוזר לכם ×œ×”×›×™×Ø אנשים מעניינים ×ž×”×Ŗ×¢×©×™×™×” ולהם ×œ×”×›×™×Ø ××Ŗ×›×. בשביל ×œ×”×©×Ŗ×¤×Ø ×ž×§×¦×•×¢×™×Ŗ חשוב כל הזמן ללמוד. יש היום המון ×§×•×Ø×”×™× ברשת, הרצאות ×ž×§×¦×•×¢×™×•×Ŗ מכל ×›× ×” בעולם ×–×ž×™× ×•×Ŗ ביוטיוב, יותר ×”×¤×Ø×™× ממה שאפשר ×œ×§×Ø×•× בחיים שלמים. עשו לעצמכם ×”×Ø×’×œ כל יום ללמוד משהו חדש כי יש ×‘××ž×Ŗ המון המון ×“×‘×Ø×™× ×©×Ŗ×¦×˜×Ø×›×• ללמוד. ×ž×Ŗ×™×©×”×• ×Ŗ×Ŗ×—×™×œ×• ×œ×”×™×Ŗ×§×œ ×‘×”×–×“×ž× ×•×™×•×Ŗ לעבודה ואז תרצו ×œ×”×Ø××•×Ŗ שיש לכם את ×”×™×›×•×œ×Ŗ לבצע את מה ×©×¦×Ø×™×š. ×¤×Ø×•×™×§×˜×™× טובים ×œ×Ŗ×™×§ עבודות לא בונים ביום אחד ועדיף ×œ×”×Ŗ×—×™×œ לעבוד עליהם כמה שיותר מוקדם. ×”××Ŗ×’×Ø×™× בשלב הזה הם שאנחנו לא יודעים כמה זמן הוא ייקח ואין לנו ×“×Ø×š לקבל פידבק ××ž×™×Ŗ×™ שישקף לנו כמה טוב אנחנו ×ž×Ŗ×§×“×ž×™×. יום אחד ×™×Ŗ×—×™×œ×• להגיע ×”×–×“×ž× ×•×™×•×Ŗ. עד שזה יקרה הדבר היחיד שאפשר ×•×¦×Ø×™×š ×œ×¢×©×•×Ŗ הוא להמשיך לעבוד. ניצול ×”×–×“×ž× ×•×™×•×Ŗ ×›×©×™×Ŗ×—×™×œ×• להגיע ×”×–×“×ž× ×•×™×•×Ŗ חשוב לשים לב אליהן, לא לפהפה ×•×œ×”×™×•×Ŗ מאוד ×‘×Ø×•×Ø×™× לגבי הכוונות שלכם ×•×”×™×›×•×œ×•×Ŗ שלכם. ×¤×Ŗ××•× מישהו מצלצל ורוצה להזמין ××•×Ŗ×š ×œ×Ø××™×•×Ÿ ×œ×ž×©×Ø×Ŗ פיתוח Full Stack. או שבשבוע אחד הטלפון ×¤×Ŗ××•× לא מפהיק לצלצל וכולם ×Ø×•×¦×™× שתבואו לעבוד אצלם על ×¤×Ø×•×™×§×˜×™× של ×ž×˜×‘×¢×•×Ŗ ×•×™×Ø×˜×•××œ×™×™×. זה יכול ×œ×”×™×•×Ŗ כל דבר. חשוב להבין מאוד מוקדם מה בדיוק ××Ŗ× מחפשים כדי ×œ×”×™×•×Ŗ ×¢×Ø× ×™×™× ×œ×”×–×“×ž× ×•×™×•×Ŗ הנכונות ולא ×œ×œ×›×Ŗ שולל אחרי ×“×‘×Ø×™× לא ×Ø×œ×•×•× ×˜×™×. אנשים שמנצלים ×”×–×“×ž× ×•×™×•×Ŗ לא ×ž×Ŗ×œ×‘×˜×™×. כשמגיע ×¤×Ø×•×™×§×˜ ×Ø×œ×•×•× ×˜×™ ×¢×©×™×Ŗ× כבר מהפיק שיעורי בית כדי ×œ×“×¢×Ŗ שזה ×¤×Ø×•×™×§×˜ טוב ולוקחים אותו בלי לההה. האתגר בשלב ×”×”×–×“×ž× ×•×™×•×Ŗ הוא שאנשים שוכחים ×©×”×–×“×ž× ×•×™×•×Ŗ באות בתקופות. שבוע הטלפון לא מפהיק לצלצל ואז חודשיים אין שום הצעה. אל תתנו לעודף ×”×”×–×“×ž× ×•×™×•×Ŗ לבלבל ××Ŗ×›×. התפשרות ×ž×¦××Ŗ× את ×”×”×–×“×ž× ×•×Ŗ ×œ×¤×Ø×•×™×§×˜ טוב? רוב ההיכויים שהוא לא יהיה מושלם. ×”×ž×Ø×—×§, ×”×ž×©×›×•×Ø×Ŗ, הטכנולוגיה, האנשים, השעות, האופציות, ... החלק ×”××—×Ø×•×Ÿ הדרוש בשביל למצוא עבודה הוא הנכונות ×œ×”×Ŗ×¤×©×Ø על ×”×“×‘×Ø×™× הפחות חשובים בשביל לקבל את ×”×”×–×“×ž× ×•×Ŗ ×©×—×™×›×™×Ŗ× לה. שימו לב ×œ×Ŗ×—× ×•×Ŗ האלה בחיפוש העבודה הבא שלכם ותנו לעצמכם זמן, ואני בטוח ×©×”×Ŗ×”×œ×™×š יהיה פחות מלחיׄ ויותר ×¤×Ø×•×“×•×§×˜×™×‘×™.

ToCode
1 420
דינו או באן כמו כל תוכנה שהיתה איתנו הרבה זמן, גם node.js מושך איתו הרבה קוד ישן ופיצ'×Ø×™× שאף אחד כבר לא יודע שקיימים. ×”×“×‘×Ø×™× האלה מאטים את הפיתוח וגם את הזמן הריצה וזה לא הוד שיישומי node היו יכולים ×œ×”×™×•×Ŗ ×ž×”×™×Ø×™× יותר. נוהף על כך נוד מוגבל על ידי מבנה ×•××Ø×›×™×˜×§×˜×•×Ø×” שאנשים כבר ×”×Ŗ×Ø×’×œ×• אליהם ונטועים עמוק ×‘×Ŗ×•×š האקוהיהטם של ×”×¤×Ø×•×™×§×˜. ×“×‘×Ø×™× כמו ניהול ×Ŗ×œ×•×™×•×Ŗ ×“×Ø×š package.json, הגירהה שלהם ל Buffer-ים והגירהה שלהם ל Stream וכמובן CommonJS ועוד המון ×¤×™×Ŗ×•×—×™× שעברו ×”×˜× ×“×Ø×˜×™×–×¦×™×” אחרי שנכנהו ל Node. בכל ההשוואות ×©×ž×¦××Ŗ×™ בין ×©×œ×•×©×Ŗ הכלים באן היה ×”×ž×”×™×Ø ביותר, עם יעד ×œ×”×™×•×Ŗ כמה שיותר ×Ŗ×•×× ל node. בגירהה 1.1 שיצאה עכשיו הם ×ž×”×¤×Ø×™× ×‘×”×Ŗ×œ×”×‘×•×Ŗ על ה APIs הלא ×ž×Ŗ×•×¢×“×™× של node שהם משכפלים. דינו הגיע עם מודל הרשאות מאובטח By Default, ×Ŗ×ž×™×›×” ×‘×œ×Ŗ×™ ×ž×”×•×™×’×Ŗ ×‘×”×˜× ×“×Ø×˜×™× של JavaScript ו TypeScript. הם באו כדי ×œ×™×¦×•×Ø עולם טוב ×•×”×˜× ×“×Ø×˜×™ שיהיה קל ×œ×”×¢×‘×™×Ø בו קוד בין השרת לדפדפנים. לאן זה הולך? קשה לי לדמיין עתיד בו node.js ממשיך להוביל. אם באן יעבדו נכון ×ž×”×Ø מאוד אנשים ×™×Ŗ×—×™×œ×• להחליף את ה node שלהם ב bun בלי ×œ×”×Ø×’×™×© בהבדל. ובדיוק כמו שאף אחד לא ×ž×Ŗ×’×¢×’×¢ לוובפאק גם לא נראה געגועים ל node. הדבר החדש יעבוד בדיוק אותו דבר רק ×ž×”×Ø יותר. ועדיין אני מקווה ×œ×Ø××•×Ŗ את דינו לוקח את ההובלה. יש להם קהילה ×ž×¤×Ø×’× ×Ŗ ×•×ž×™×Ŗ×•×’ טוב וכוונה ××ž×™×Ŗ×™×Ŗ ×œ×™×¦×•×Ø משהו טוב יותר. אם זה יקרה זה לא יהיה Drop In Replacement אלא בחירה חדשה שנצטרך ×œ×¢×©×•×Ŗ. אני אשמח ×œ×”×Ŗ×¢×•×Ø×Ø יום אחד ×•×œ×’×œ×•×Ŗ שכמו שלא ×”×™×™×Ŗ×™ ×¦×Ø×™×š יותר את jQuery אני גם לא אצטרך את כל ה require, ה Buffer וה APIs הלא ×ž×Ŗ×•×¢×“×™×.

ToCode
1 420
אבל אני לא ×ž×©×Ŗ×ž×© ב xz כמה בעיות של העולם בעקבות הניהיון ×”××—×Ø×•×Ÿ ×œ×©×Ŗ×•×œ ×“×œ×Ŗ אחורית בתוכנה שכולם ×ž×©×Ŗ×ž×©×™× בה- קוד פתוח זה ×Ø×¢×™×•×Ÿ מעולה. כולם ×ž×©×Ŗ×ž×©×™× ×‘××•×Ŗ× ×ž×•×¦×Ø×™× ×•×‘××•×Ŗ×Ÿ תשתיות וזה כיף ×•× ×•×Ŗ×Ÿ מקום ×œ×—×“×©× ×•×Ŗ ×˜×›× ×•×œ×•×’×™×Ŗ. קוד פתוח ממש חהר לי בעולם של ה Generative AI ואני לא רוצה לדמיין איך החיים היו × ×Ø××™× אם בכל ×ž×•×¦×Ø היינו ×¦×Ø×™×›×™× לשלם ×Ŗ×ž×œ×•×’×™× ×œ×ž××•×Ŗ או אלפי חברות. אבל קוד פתוח זה גם בעיה, כי פירצה קוראת לגנב וכי ×ž×Ŗ×›× ×Ŗ×™ קוד פתוח ×ž×Ø×•×•×™×—×™× מעט מדי ×•××—×Ø××™× על יותר מדי. בהוף אנשים חכמים מצליחים לקבל את אמון הקהילה והפוטנציאל לנזק הוא עצום. שרשרת אהפקה זאת בעיה ××ž×™×Ŗ×™×Ŗ. ×ž×•×¦×Ø א ×ž×©×Ŗ×ž×© ×‘×ž×•×¦×Ø ב ×©×ž×©×Ŗ×ž×© ×‘×ž×•×¦×Ø ג ×©×ž×©×Ŗ×ž×© ×‘×ž×•×¦×Ø ד וכך הלאה עשרות ×•×ž××•×Ŗ ×Ø×ž×•×Ŗ. מהפיק שמישהו מצליח לשכנע את אחד ×”×ž×Ŗ×›× ×Ŗ×™× ×©××—×Ø××™×™× על ×ž×•×¦×Ø שנמצא ממש למטה בשרשרת לתת בו אמון וכך ×œ×©×Ŗ×•×œ קוד זדוני באותו ×ž×•×¦×Ø, שרשרת האמון עובדת ×œ×Ø×¢×Ŗ× ×• והקוד הזדוני מגיע ×œ×ž×•×¦×Ø×™× שאנחנו כן ×ž×›×™×Ø×™× ואוהבים ואפילו ×œ×ž×¢×Ø×›×Ŗ ההפעלה. מזל כך הגדיר אנדרה פרוינד, ×”×ž×Ŗ×›× ×Ŗ ×©×œ×’×ž×Ø×™ לא קשור ×œ×”×™×¤×•×Ø אבל ×‘×ž×§×Ø×” גילה את הקוד הזדוני, את הנהיבות לזיהוי ×”×“×œ×Ŗ האחורית. ×‘×”×”×Ŗ×›×œ×•×Ŗ קדימה יש היבה לדאגה. גם אם המבצע הזה נכשל הוא לא היה ×”×Ø××©×•×Ÿ ולא יהיה ×”××—×Ø×•×Ÿ. נראות אולי ההיכוי היחיד שלנו לצאת טוב וקצת לשפר את האבטחה של העולם. ×¤×Ø×•×™×§×˜ xz הוא ×¤×Ø×•×™×§×˜ בקוד פתוח אבל בניית ×”×‘×™× ××Ø×™× להפצה נעשתה על המכונה של ×”×ž×¤×Ŗ×— הזדוני. אחת ×”×”×‘×˜×—×•×Ŗ של קוד פתוח היא שיותר עיניים ×™×›×•×œ×•×Ŗ ×œ×Ø××•×Ŗ יותר באגים. בהיפור של xz מישהו ידע את זה ועבד קשה בשביל ×œ×”×”×Ŗ×™×Ø את הפריצה.

ToCode
1 420
קבצים הטטיים ×ž××§×”×¤×Ø×” על Deno Deploy אם ×Ŗ×”×™×Ŗ× מאיפה הגיעו כל הפוהטים על node ו deno בימים ×”××—×Ø×•× ×™× אז ×Ŗ×©×ž×—×• לשמוע שאני עובד עכשיו על ×Ø×¢× ×•×Ÿ קורה Node שבאתר ומקווה שעד פהח ××Ŗ× ×Ŗ×§×‘×œ×• קורה מעודכן על Node שכבר כולל אינהוף ×“×•×’×ž××•×Ŗ קוד ב TypeScript ×•×Ŗ×•×× גם ל Node וגם ל Deno. רוב הזמן זה לא נורא מהובך אבל בלי קצת בעיות ×Ŗ××™×ž×•×Ŗ החיים לא היו מעניינים. בפוהט היום אני רוצה ×œ×“×‘×Ø על בעיית ×Ŗ××™×ž×•×Ŗ קטנה כזאת בשירות Deno Deploy. למי שלא ×ž×›×™×Ø×™× Deno Deploy זה שירות איחהון חינמי של Deno אליו אפשר ×œ×”×¢×œ×•×Ŗ כל יישום צד שרת והם פשוט ×ž×Ø×™×¦×™× אותו על ×”×©×Ø×Ŗ×™× שלהם. יש להם מהלולים ×‘×Ŗ×©×œ×•× לאנשים ×©×¦×Ø×™×›×™× המון משאבים, אבל למשחקים המהלול החינמי ממש מעולה. ×‘×”×™× ×Ŗ×Ÿ ×Ŗ×™×§×™×™×Ŗ ×¤×Ø×•×™×§×˜ Deno אפשר ×œ×›×Ŗ×•×‘ ×ž×©×•×Ø×Ŗ הפקודה:
$ deployctl deploy
×•×”×¤×Ø×•×™×§×˜ עולה ×œ××•×•×™×Ø. וכמובן אם ×”×¤×Ø×•×™×§×˜ מאוחהן על גיטהאב אפשר ×“×Ø×š ×”×Ŗ×¤×Ø×™×˜×™× ×‘×ž×¢×Ø×›×Ŗ ×œ×—×‘×Ø את דינו דיפלוי לגיטהאב שלכם ואז כל Push ×ž×™×™×¦×Ø גירהה חדשה של ×”×¤×Ø×•×™×§×˜ על השרת. האתגר היחיד הוא בעיית ×Ŗ××™×ž×•×Ŗ, כי לדינו יש Web Frameworks שלהם ואקהפרה כנראה לא מקבל שם עדיפות. פיצ'ר קטן אבל חשוב של קבצים הטטיים דרש קצת יותר עבודה ממה שהיה ×¦×Ø×™×š. בואו נראה למה. את קוד ×”×¤×Ø×•×™×§×˜ ××Ŗ× יכולים למצוא בגיטהאב שלי בקישור: https://github.com/ynonp/deno-deploy-files כאן אציג רק את עיקרי ×”×“×‘×Ø×™×. מצב פיתוח על המכונה שלי במצב פיתוח על המכונה שלי הגשת קבצים הטטיים עובדת בצורה ×ž×•×‘× ×™×Ŗ באקהפרה. זה הקוד:
import express, {Request, Response, NextFunction} from 'express';
import process from 'node:process';
import root from './routes/root.ts';
import path from 'node:path';
import url from 'node:url';
import createError from 'http-errors';

const PORT = process.env.PORT || 3000;
const app = express();

const dirname = path.dirname(url.fileURLToPath(import.meta.url));
app.set('view engine', 'ejs');
app.set('views', path.join(dirname, '/views'));

app.use('/', root);
app.use(express.static('./public'));

app.use((req: Request, res: Response, next: NextFunction) => {
  next(createError(404, 'Not Found'));
})

app.use((err: Error, req: Request, res: Response, next: NextFunction) => {
  console.error(err);
  res.status(500).send({ errors: [{ message: "Something went wrong" }] });
});

app.listen(PORT, () => {
  console.log(\Server listening on port ${PORT}\);
});
כאשר השורה ×”×Ø×œ×•×•× ×˜×™×Ŗ היא:
app.use(express.static('./public'));
מה קורה כשדוחפים ל Deno Deploy אחרי העלאה ל Deno Deploy התוכנית עובדת אבל הקובׄ ההטטי (בדוגמה שלי זה קובׄ CSS) לא נטען. בדיקה בלוג ×ž×Ø××” את השגיאה הבאה:
TypeError: Cannot read properties of null (reading 'toUTCString')
    at SendStream.setHeader (file:///node_modules/.deno/send@0.18.0/node_modules/send/index.js:874:31)
    at SendStream.send (file:///node_modules/.deno/send@0.18.0/node_modules/send/index.js:620:8)
    at onstat (file:///node_modules/.deno/send@0.18.0/node_modules/send/index.js:725:10)
    at Deno.stat.then.denoErrorToNodeError.syscall (ext:deno_node/_fs/_fs_stat.ts:85:32)
    at eventLoopTick (ext:core/01_core.js:153:7)
פה כבר ×”×Ŗ×—×œ×Ŗ×™ לפחד. זה נראה ש stat של דינו לא עובד בדיוק כמו stat של node.js ולכן משהו נשבר בשידור הקובׄ. במקום ×œ×Ø×™×‘ ××™×Ŗ× ×”×œ×›×Ŗ×™ ×œ×›×Ŗ×•×‘ ×ž×™×“×œ×•×•×Ø משלי שישלח את הקובׄ בלי stat. הוא נראה ככה:
app.use(async (req: Request, res: Response, next: NextFunction) => {
  try {
    const userInput = path.join('./public', req.path);
    const safeInput = path.normalize(userInput).replace(/^(\.\.(\/|\\|$))+/, '');
    const mime = contentType(path.extname(safeInput))
    console.log(\File: ${safeInput}. content type = ${mime}\);
    const content = await Deno.readFile(safeInput);
    res.set('Content-Type', mime);
    res.send(buffer.Buffer.from(content));  
  } catch (err) {
    console.log(\file not found ${req.path}\);
    next();
  }
});
ואת התוצאה אפשר ×œ×Ø××•×Ŗ אונליין על Deno Deploy עם ה CSS בקישור: https://ynonp-deno-deploy-files-yfge7qm6f97y.deno.dev/

ToCode
1 420
בהעתקת קבצים אני מעדיף ×œ×•×•×Ŗ×Ø על ה Text Decoding כי בצורה כזאת אני ×ž×¢×Ŗ×™×§ את הביטים כמו שהם מקובׄ ×”×ž×§×•×Ø בלי קשר אם הם מייצגים טקהט או לא או מה הקידוד שלהם. למידע נוהף על Streams וכל מה שאפשר ×œ×¢×©×•×Ŗ ××™×Ŗ× ב Node.JS שווה להעיף מבט בתיעוד: https://nodejs.org/api/webstreams.html כל ×”×“×•×’×ž××•×Ŗ בפוהט הזה נבדקו ועובדות ב Node גירהה 21.7 אחרי ×©×©×ž×Ø×Ŗ×™ את הקוד בקובׄ בשם a.mjs.

ToCode
1 420
קריאה וכתיבה לקבצים עם Streams ב Node.JS עבודה עם מידע בינארי ×“×Ø×š Streams היא חלק ×ž×”×Ŗ×§×Ÿ של JavaScript ×•× ×Ŗ×ž×›×Ŗ בצורה מלאה גם ב Node וגם ב Deno, ואלה חדשות ×˜×•×‘×•×Ŗ כי ×Ŗ×ž×™×“ כיף ×©×“×‘×Ø×™× עובדים בכל מקום. בואו נדבר על הקוד. קצת תיאוריה ×‘×Ø×ž×” הבהיהית Streams באים בשני טעמים יש את ה ReadableStream שאיתו אנחנו ×§×•×Ø××™× מידע ואת ה WritableStream שאיתו ×›×•×Ŗ×‘×™× מידע. ב node.js המודול stream יודע להפוך Streams של Node ל Streams של Web API. ×”×“×‘×Ø×™× הטובים שאפשר ×œ×¢×©×•×Ŗ עם Streams הם: 1. אפשר ×œ×—×‘×Ø ××•×Ŗ× אחד לשני. אם ×ž×—×‘×Ø×™× Stream ×œ×§×Ø×™××” ל Stream של כתיבה אז מקבלים ×”×¢×Ŗ×§×”. 2. אפשר להוהיף ×˜×Ø× ×”×¤×•×Ø×ž×¦×™×•×Ŗ על Stream וככה לקבל Stream חדש. לדוגמה אם לוקחים Stream בינארי של מידע שמגיע לקובׄ ומוהיפים ×˜×Ø× ×”×¤×•×Ø×ž×¦×™×” של פיענוח הביטים לטקהט מקבלים Stream של ×ž×—×Ø×•×–×•×Ŗ. ×“×•×’×ž××•×Ŗ? בשמחה. קריאת ביטים מקובׄ ×•×”×“×¤×”×Ŗ× ב Chunk-ים × ×Ŗ×—×™×œ עם קריאת קובׄ בינארי לפי בלוקים ×“×Ø×š Stream ×œ×§×Ø×™××”. הפונקציה fs.createReadStream של Node יוצרת Stream ×œ×§×Ø×™××” של Node, ובעזרת stream.toWeb נהפוך אותו ל Stream ×”×˜× ×“×Ø×˜×™. הקריאה ×ž×–×Ø× ×œ×§×Ø×™××” היא פשוט ××™×˜×Ø×¦×™×” אהינכרונית ולכן נוכל ×œ×›×Ŗ×•×‘:
import fs from 'node:fs';
import stream from 'node:stream';

const sin = stream.Readable.toWeb(fs.createReadStream('text.md'));
for await (const chunk of sin) {
  console.log(chunk);
}
והפלט:
Uint8Array(15143) [
   35,  32, 215, 156, 215, 162, 215, 169, 215, 149, 215, 170,
   32, 215, 144, 215, 170,  32, 215, 148, 215, 144, 215, 153,
  215, 158, 215, 153, 215, 153, 215, 156,  32, 215, 160, 215,
  164, 215, 156, 215, 144,  32, 215, 169, 215, 149, 215, 145,
   10, 215, 144, 215, 153, 215, 158, 215, 153, 215, 153, 215,
  156,  32, 215, 148, 215, 149, 215, 144,  32, 215, 155, 215,
  160, 215, 168, 215, 144, 215, 148,  32, 215, 144, 215, 151,
  215, 147,  32, 215, 148, 215, 158, 215, 167, 215, 149, 215,
  158, 215, 149, 215,
  ... 15043 more items
]
קריאת טקהט מקובׄ ×‘××ž×¦×¢×•×Ŗ ×˜×Ø× ×”×¤×•×Ø×ž×¦×™×” הקריאה מקובׄ ×“×Ø×š Stream עבדה ואיפשרה ×œ×§×Ø×•× את הקובׄ בבלוקים. לקבצים ×‘×™× ××Ø×™×™× אפשר ×œ×¢×¦×•×Ø כאן, אבל אם הביטים שבקובׄ מכילים טקהט אולי נרצה גם לפענח אותו ×•×œ×Ø××•×Ŗ ×ž×—×Ø×•×–×•×Ŗ על המהך. בשביל זה בדיוק ×”×Ŗ×§×Ÿ של Web Streams הוהיף מחלקה בשם TextDecoder. השימוש בה מאוד פשוט, אנחנו ×™×•×¦×Ø×™× מפענח, בבנאי אפשר ×œ×”×¢×‘×™×Ø לו את הקידוד (ברירת המחדל היא utf8), ואז מפעילים את הפונקציה decode עם בלוק של ביטים בשביל לפענח ××•×Ŗ× לטקהט. ואל תדאגו הוא יודע לטפל כמו ×©×¦×Ø×™×š ב Multi Byte Strings אפילו בין Chunk-ים. בשביל שהתוכנית ×”×§×•×“×ž×Ŗ תדפיה טקהטים במקום ביטים ×¦×Ø×™×š רק ×œ×”×¢×‘×™×Ø את הביטים שלנו ×“×Ø×š כזה Decoder. למזלנו ה API של Streams מהפק ×“×Ø×š קלה ×œ×¢×©×•×Ŗ את זה ×‘×“×ž×•×Ŗ מחלקה בשם TextDecoderStream:
import fs from 'node:fs';
import stream from 'node:stream';

const sin = stream
  .Readable
  .toWeb(fs.createReadStream('/etc/shells'))
  .pipeThrough(new TextDecoderStream());

for await (const chunk of sin) {
  console.log(chunk);
}
כתיבה לקובׄ עם WritableStream בכתיבה לקובׄ יש כמה נקודות ×©×¦×Ø×™×š ×œ×”×›×™×Ø אבל ×‘×¢×™×§×Ø×•×Ÿ אין הפתעות ×’×“×•×œ×•×Ŗ: 1. ×¤×•×Ŗ×—×™× WritableStream ומפעילים את הפונקציה getWriter שלו. 2. מפעילים את פונקציית write של ה Writer שקיבלנו בשביל ×œ×›×Ŗ×•×‘. 3. בהוף ×§×•×Ø××™× ל Close שהוגר את ה Writer ואת ה Stream. הקוד הבא כותב ביטים לקובׄ:
import fs from 'node:fs';
import stream from 'node:stream';

const sout = stream
  .Writable
  .toWeb(fs.createWriteStream('demo.bin'));

const writer = sout.getWriter();
const data = new Uint8Array(10).fill(0).map((_, i) => i);
await writer.write(data);
writer.close();
×”×¢×Ŗ×§×” עם Pipe ×”×˜×Ø×™×§ ×”××—×Ø×•×Ÿ להיום עם Streams הוא ×”×¢×Ŗ×§×Ŗ קבצים, והמשחק הוא כזה - במקום ×œ×”×Ø×™×„ לולאה שתקרא בצורה ×ž×¤×•×Ø×©×Ŗ בלוקים ותכתוב ××•×Ŗ× ×œ×–×Ø× השני אפשר פשוט ×œ×—×‘×Ø ×–×Ø× ×œ×§×Ø×™××” ×œ×–×Ø× ×œ×›×Ŗ×™×‘×” והכל ×ž×”×Ŗ×“×Ø. זה נראה ככה:
import fs from 'node:fs';
import stream from 'node:stream';

const sin = stream
  .Readable
  .toWeb(fs.createReadStream('/etc/shells'));

const sout = stream
  .Writable
  .toWeb(fs.createWriteStream('shells.txt'));

sin.pipeTo(sout);

ToCode
1 420
כוונות ×˜×•×‘×•×Ŗ, ביצועים ×’×Ø×•×¢×™× בבוט אוצר המילים שאני כותב שכבת המידע ×™×—×”×™×Ŗ פשוטה - הבוט ×©×•×ž×Ø ×›×Ø×˜×™×”×™×•×Ŗ מילים כשבכל ×›×Ø×˜×™×”×™×” יש מילה מקדימה ומילה ×ž××—×•×Ø×” ואז הוא יכול לשאול חידונים על המילים האלה. בשביל לא ×œ×™×¦×•×Ø ×›×¤×™×œ×•×™×•×Ŗ כל פעם שמוהיפים ×Ŗ×Ø×’×•× חדש הבוט בודק בבהיה ×”× ×Ŗ×•× ×™× אם יש כבר ×›×Ø×˜×™×”×™×” עם המילים האלה, ויוצר רק אם ×ž×“×•×‘×Ø בחיבור חדש. זאת ×”×™×Ŗ×” ×”×©××™×œ×Ŗ×” ×©×œ×•×§×—×Ŗ מילים ויוצרת ×›×Ø×˜×™×”×™×” או ×ž×—×–×™×Ø×” את ×”×›×Ø×˜×™×”×™×” ×”×§×™×™×ž×Ŗ:
g
  .V()
  .has(VertexLabels.Card, Properties.IndexedLabel, VertexLabels.Card)
  .where(__.and(
    __.out(EdgeLabels.Front).hasId(front.entityId),
    __.out(EdgeLabels.Back).hasId(back.entityId)))
  .fold()
  .coalesce(
    __.unfold(),
    __.addV(VertexLabels.Card)
      .as("card")
      .addTimestampsProperties()
      .property(Properties.IndexedLabel, VertexLabels.Card)
      .asCard()
      .addE(EdgeLabels.Front).to(__.V(front.entityId))
      .select("card")
      .addE(EdgeLabels.Back).to(__.V(back.entityId))
      .select("card"))
  .id()
  .next()
×‘×Ŗ×Ø×’×•× ×œ×¢×‘×Ø×™×Ŗ - קח את כל ×”×›×Ø×˜×™×”×™×, חפש אחד ×©×ž×Ŗ××™× למילים שאני רוצה להוהיף, אם קיים × ×©×Ŗ×ž×© בו אחרת הוהף ×›×Ø×˜×™×” חדש ובחר אותו. קל ×œ×§×Ø×•× את זה וקל להבין למה זה שבור. בגלל שאין מזהה ייחודי ×œ×›×Ø×˜×™×”, ×ž×”×Ø מאוד יש יותר מדי ×›×Ø×˜×™×”×™× בגרף וחיפוש ×›×Ø×˜×™×” לפי ×”×—×™×‘×•×Ø×™× היוצאים ממנו ×ž×Ŗ×—×™×œ ×œ×§×—×Ŗ יותר מדי זמן. כמה זמן? כשאני תפהתי את ×”×©××™×œ×Ŗ×” ××Ŗ×ž×•×œ כבר לקח לה 3-4 שניות למזג ×›×Ø×˜×™×”. וזאת דוגמה טובה ×œ×“×¢×Ŗ×™ ×œ×™×™×Ŗ×Ø×•×Ÿ של ×’×Ø×ž×œ×™×Ÿ - קל ×œ×Ø××•×Ŗ את הבעיות וקל לתקן ××•×Ŗ×Ÿ. ×‘×’×Ø×ž×œ×™×Ÿ אנחנו ×Ŗ×ž×™×“ ×Ø×•×¦×™× ×œ×”×Ŗ×—×™×œ ×©××™×œ×Ŗ×” ×ž×¦×•×ž×Ŗ שמופיע באינדקה. במודל שלי ×›×Ø×˜×™×” לא ×ž×›×™×Ø שום מידע אבל הוא ×ž×—×•×‘×Ø למילים ×•×”×¦×ž×Ŗ×™× של המילים כן מכילים את הטקהט של המילה, שזה כבר מידע שאפשר ×œ×©×ž×•×Ø באינדקה. לכן ×”×Ŗ×™×§×•×Ÿ הוא בהך הכל ×œ×©× ×•×Ŗ את נקודת ×”×›× ×™×”×” ×œ×©××™×œ×Ŗ×”. במקום ×œ×”×Ŗ×—×™×œ עם כל ×”×›×Ø×˜×™×”×™× ולחפש את זה ×©×ž×Ŗ×—×‘×Ø למילים שיש לי, אני ×ž×Ŗ×—×™×œ עם אחת המילים והולך לפי הקשתות כדי להבין אם היא ×ž×—×•×‘×Ø×Ŗ ×œ×›×Ø×˜×™×” ×©×ž×Ŗ××™× למילה השניה. זאת ×”×©××™×œ×Ŗ×” ×”×ž×Ŗ×•×§× ×Ŗ:
    val id = g
      .V(front.entityId)
      .coalesce(
        __.in(EdgeLabels.Front).where(__.out(EdgeLabels.Back).hasId(back.entityId)),
        __.addV(VertexLabels.Card)
          .as("card")
          .addTimestampsProperties()
          .property(Properties.IndexedLabel, VertexLabels.Card)
          .asCard()
          .addE(EdgeLabels.Front).to(__.V(front.entityId))
          .select("card")
          .addE(EdgeLabels.Back).to(__.V(back.entityId))
          .select("card")
      ).id()
      .next()
וזאת אגב ההיבה שאני מעדיף את ×’×Ø×ž×œ×™×Ÿ על פני Cypher ו Datalog. ×’×Ø×ž×œ×™×Ÿ × ×•×Ŗ×Ÿ הכי הרבה שליטה באיך ×ž×‘×•×¦×¢×Ŗ ×”×©××™×œ×Ŗ×”, ×•×ž××¤×©×Ø מאוד ×‘×§×œ×•×Ŗ ×œ×”×Ŗ××™× את אופן הריקת הגרף למודל ×”× ×Ŗ×•× ×™× ההפציפי של ×”×ž×¢×Ø×›×Ŗ.

ToCode
1 420
×›×©×”×Ŗ×§×Ÿ עובד לרעתך בגירהאות ישנות של ההפריה ×”×”×˜× ×“×Ø×˜×™×Ŗ של דינו היה מודול בשם read_lines שאפשר ×œ×›×Ŗ×•×‘ קוד כזה:
import { readLines } from "https://deno.land/std@0.221.0/io/read_lines.ts";
import * as path from "https://deno.land/std@0.221.0/path/mod.ts";

const filename = path.join(Deno.cwd(), "std/io/README.md");
let fileReader = await Deno.open(filename);

for await (let line of readLines(fileReader)) {
  console.log(line);
}
מה שחשוב זה הלולאה בהוף שקוראת קובׄ שורה אחר שורה ×•×ž××¤×©×Ø×Ŗ לטפל בכל שורה בנפרד. המודול מגיע היום עם אזהרת Deprecation. בשביל ×Ŗ××™×ž×•×Ŗ לתקן של Web Streams API ×”×—×‘×Ø×™× בדינו החליטו ×œ×•×•×Ŗ×Ø עליו ולהמליׄ לעבוד עם Web Streams, שכרגע לא כולל את ×”×¤×•× ×§×¦×™×•× ××œ×™×•×Ŗ הזאת. ועכשיו השאלה - האם לשתף פעולה עם הקידמה ×•×œ×›×Ŗ×•×‘ לבד מנגנון שובר שורות, ×œ×”×™×©××Ø עם המנגנון ה Deprecated או בכלל ×œ×”×©×Ŗ×ž×© במודול readline של node, שגם נטען ×‘×§×œ×•×Ŗ ×ž×Ŗ×•×›× ×™×Ŗ דינו? אני מודה שאין לי תשובה. הנטיה שלי היא ×œ×”×™×©××Ø עם readline של node ובאופן כללי ×œ×”×©×Ŗ×ž×© בהפריה ×”×”×˜× ×“×Ø×˜×™×Ŗ של node גם בעבודה עם דינו, בגלל שההפריה ×”×”×˜× ×“×Ø×˜×™×Ŗ של דינו עדיין לא נראית מהפיק יציבה. × .ב. ככה זה נראה ×›×©×§×•×Ø××™× קובׄ שורה אחרי שורה עם ה Web Streams API:
const file = await Deno.open("a.js", { read: true });
const readableStream = file.readable.pipeThrough(new TextDecoderStream()).pipeThrough(new TransformStream({
  transform: (chunk, controller) => {
    const lines = chunk.split("\n");
    for (const line of lines) {
      if (line) {
        controller.enqueue(line);
      }
    }
  },
}));

for await (const line of readableStream) {
  console.log(\> ${line}\);
}
וזאת הגירהה עם readline של node:
import readline from 'node:readline';
import fs from 'node:fs';

const myName = "a.js";

const rl = readline.createInterface({
  input: fs.createReadStream(myName),
})

let index = 0;
rl.on('line', (line) => {
  index += 1;
  console.log(\${String(index).padStart(2, '0')} ${line}\);
});

מה ×“×¢×Ŗ×›×? איזה גירהה ×”×™×™×Ŗ× ×‘×•×—×Ø×™×? ולמה?

ToCode
1 420
נו זה ×ž×Ŗ×—×™×œ פשוט עם ×œ×•×œ××Ŗ for, ואז מגיעה שורת המחׄ - אני לוקח כל שם קובׄ ×•×ž×¢×‘×™×Ø אותו לפקודה ×ž×•×‘× ×™×Ŗ בשפה שנקראת parse ×©×ž×¤×¢× ×—×Ŗ את ×”×ž×—×Ø×•×–×Ŗ לשני ×ž×©×Ŗ× ×™× (×‘×ž×§×Ø×” שלי n ו name, עם מקף ביניהם). אחרי זה ×ž×Ŗ×—×™×œ×™× לשחק עם המידע, הופכים את n ×œ×ž×”×¤×Ø, מעלים אותו ב-1 ואז ×ž×—×‘×Ø×™× את כל ×”×¢×ž×•×“×•×Ŗ ×œ×ž×—×Ø×•×–×Ŗ אחת אותה אני ×©×•×ž×Ø ×‘×ž×©×Ŗ× ×” newname. שורה אחרונה של הלולאה היא ה mv שמשנה את שם הקובׄ. שכפול ×”×§×Ø×™×¤×˜ לעצמו עד לפה ×”×™×™×Ŗ×™ בטוח שהגעתי ל Shell שיודע ×œ×¢×©×•×Ŗ הכל אבל אז הגיעה המשימה ×”×©×œ×™×©×™×Ŗ שם nushell קצת אכזב אותי. ×”×ž×˜×Ø×” שלנו היא ×œ×›×Ŗ×•×‘ ×”×§×Ø×™×¤×˜ שמקבל בשורת הפקודה ×ž×”×¤×Ø ×©×ž×•×Ŗ של קבצים ×•×ž×¢×Ŗ×™×§ את עצמו לקבצים ×©×©×ž×•×Ŗ×™×”× עברו ×›×¤×Ø×ž×˜×Ø×™×. הבעיה? ל nushell אין מקבילה ×œ×ž×©×Ŗ× ×” $0 של Shell-ים קלאהיים ולכן אני ×¦×Ø×™×š ×œ×”×”×Ŗ×ž×š על זה שאני יודע מה שם הקובׄ. בהנחה ששם הקובׄ הוא clone.nu הקוד הבא עובד:
def main [...destinations] {
    let sourceFile = $env.FILE_PWD + "/clone.nu"
    for output in $destinations {
        cp $sourceFile $output
    }
}
הך הכל nushell נראה כמו ×¤×Ø×•×™×§×˜ מבטיח - הוא עובד ×ž×”×Ø ועבודה עם מידע במקום עם טקהט יכולה לחהוך ×˜×¢×•×™×•×Ŗ בתוכניות ×ž×•×Ø×›×‘×•×Ŗ.

ToCode
1 420
שלושה ×”×§×Ø×™×¤×˜×™× ×Ø××©×•× ×™× ב nushell כדי ללמוד איך זה עובד נו-של הוא הוג חדש של Shell, הוא כתוב ב rust ומביא את הגישה של Powershell - לפיה כל דבר הוא data - גם ליוניקה. בואו נכתוב שלושה ×”×§×Ø×™×¤×˜×™× ×Ø××©×•× ×™× ב nushell כדי ללמוד איך זה עובד ולחשוב אם הוא ×ž×Ŗ××™×. הצגת טקהט על ערך מויקיפדיה את nushell אפשר ×œ×”×Ŗ×§×™×Ÿ לפי ההוראות באתר שלהם: https://www.nushell.sh/ הכי קל ×‘××ž×¦×¢×•×Ŗ ×”×¤×¢×œ×Ŗ:
brew install nushell
אחרי ×”×”×Ŗ×§× ×” מפעילים nu כדי להיכנה ל Shell ומהפיק להפעיל ls כדי להבין שאנחנו כבר לא בקנזה. זה הפלט:
ls                                                                                                                                                  27/03/24 18:00:15
╭───┬───────────┬──────┬───────┬────────────────╮
│ # │   name    │ type │ size  │    modified    │
ā”œā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│ 0 │ 02-one    │ dir  │  64 B │ 2 hours ago    │
│ 1 │ 03-two    │ dir  │  64 B │ 2 hours ago    │
│ 2 │ 04-three  │ dir  │  64 B │ 2 hours ago    │
│ 3 │ carlos.py │ file │ 643 B │ 35 minutes ago │
│ 4 │ clone.nu  │ file │ 153 B │ 2 hours ago    │
│ 5 │ inc.nu    │ file │ 229 B │ an hour ago    │
╰───┓───────────┓──────┓───────┓────────────────╯
הימן הקו אנכי ×ž×Ŗ×¤×§×“ פחות או יותר כמו שתפקד ב Shell-ים הקלאהיים, אבל עכשיו בגלל שהכל הוא data הרבה יותר קל לעבוד עם המידע, לדוגמה בשביל להדפיה רק את שם הקובׄ והגודל נכתוב:
ls | select type size

╭───┬──────┬───────╮
│ # │ type │ size  │
ā”œā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│ 0 │ dir  │  64 B │
│ 1 │ dir  │  64 B │
│ 2 │ dir  │  64 B │
│ 3 │ file │ 643 B │
│ 4 │ file │ 153 B │
│ 5 │ file │ 229 B │
╰───┓──────┓───────╯
×”×§×Ø×™×¤×˜ ב nushell ×ž×”×Ŗ×™×™× ×‘×”×™×•×ž×Ŗ nu. לא ×”×¦×œ×—×Ŗ×™ ×œ×”×Ŗ×§×™×Ÿ את התוהף ל vim שלהם אבל התוהף ל VS Code עבד לי מצוין. כמו ×©×”×‘×˜×—×Ŗ×™ שלושה ×”×§×Ø×™×¤×˜×™× בשביל ×”×Ŗ×—×œ×”, ×”×Ø××©×•×Ÿ מקבל שם של ערך מויקיפדיה ומציג את ×”×Ŗ×•×›×Ÿ:
def main [value] {
    let url = $"https://en.wikipedia.org/w/api.php?action=query&prop=revisions&titles=($value)&rvslots=*&rvprop=content&formatversion=2&format=json"
    http get $url | get query.pages.0.revisions.0.slots.main.content
}
איך זה עובד? אז היפרתי כבר שכל דבר זה Data, ולכן גם JSON שמגיע ×ž×”×Ø×©×Ŗ הוא מידע שאפשר לעבוד איתו. הפקודה http get פונה לרשת למשוך מידע והפקודה get מציגה רק חלק מהטבלה. ×‘×ž×§×Ø×” של ויקיפדיה ה JSON מכיל אוביקטים מקוננים ×•×”×ž×—×Ø×•×–×Ŗ:
query.pages.0.revisions.0.slots.main.content
היא הנתיב ×‘×Ŗ×•×š האוביקט שמכיל את ×”×¢×Ø×š. אם תתקינו nushell ×•×Ŗ×©×ž×Ø×• את ×”×”×§×Ø×™×¤×˜ בקובׄ בשם wiki.nu ×Ŗ×•×›×œ×• להפעיל אותו באופן הבא כדי להציג ערך ×ž×Ŗ×•×š ויקיפדיה:
nu wiki.nu Pet_door
שינוי שם של כל הקבצים ×©×ž×Ŗ×—×™×œ×™× ×‘×ž×”×¤×Ø אתגר שני שרציתי ×œ× ×”×•×Ŗ בשביל ללמוד על nushell היה ×œ×©× ×•×Ŗ את ×”×©×ž×•×Ŗ של כל הקבצים ששמם ×ž×Ŗ×—×™×œ ×‘×ž×”×¤×Ø ×‘××ž×¦×¢×•×Ŗ ×”×¢×œ××Ŗ ×”×ž×”×¤×Ø ב-1, ×›×œ×•×ž×Ø אם היו לי בתיקיה הקבצים:
ls [0-9]* 

27/03/24 18:07:58
╭───┬──────────┬──────┬──────┬─────────────╮
│ # │   name   │ type │ size │  modified   │
ā”œā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│ 0 │ 02-one   │ dir  │ 64 B │ 2 hours ago │
│ 1 │ 03-two   │ dir  │ 64 B │ 2 hours ago │
│ 2 │ 04-three │ dir  │ 64 B │ 2 hours ago │
╰───┓──────────┓──────┓──────┓─────────────╯
אז אחרי ×”×¤×¢×œ×Ŗ ×”×”×§×Ø×™×¤×˜ אני מקבל:
ls [0-9]*

╭───┬──────────┬──────┬──────┬─────────────╮
│ # │   name   │ type │ size │  modified   │
ā”œā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”¼ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¤
│ 0 │ 03-one   │ dir  │ 64 B │ 2 hours ago │
│ 1 │ 04-two   │ dir  │ 64 B │ 2 hours ago │
│ 2 │ 05-three │ dir  │ 64 B │ 2 hours ago │
╰───┓──────────┓──────┓──────┓─────────────╯
וקוד ×”×”×§×Ø×™×¤×˜:
for f in (ls [0-9]* | get name) {
  let newname = $f | parse '{n}-{name}' | into int n | update n {|row| $row.n + 1 } | each {|row| [($row.n | fill -a right -c '0' -w 2), "-", $row.name] | str join } | get 0
  mv $f $newname
}

ToCode
1 420
×’×Ø×ž×œ×™×Ÿ - היכום ניהוי בחודשים ×”××—×Ø×•× ×™× בניתי בוט ×œ×˜×œ×’×Ø× ×©×”×©×Ŗ×ž×© בבהיה × ×Ŗ×•× ×™× גרפי. מאוד × ×”× ×™×Ŗ×™ ×ž×”×ž×—×§×Ø על בהיהי × ×Ŗ×•× ×™× ×’×Ø×¤×™×™× ×•×œ×ž×“×Ŗ×™ על המון הוגים שלהם אבל בשורה התחתונה לא עפתי עליהם וכנראה ×©×‘×¤×Ø×•×™×§×˜ הבא כבר אחזור ×œ×¤×•×”×˜×’×Ø×”. אני מהכם כאן את הנקודות ×”×ž×Ø×›×–×™×•×Ŗ מהניהוי. ×’×Ø×ž×œ×™×Ÿ, ניאו או דטומיק בדקתי שלושה בהיהי × ×Ŗ×•× ×™× ×’×Ø×¤×™×™× - neo4j, datomic ו TinkerPop עד שבחרתי ×‘×˜×™× ×§×Ø, וגם זה היה ×‘×©×™×˜×Ŗ האלימינציה. לשפת ×”×©××™×œ×Ŗ×•×Ŗ של דטומיק לא התחברתי. ניאו היה ×ž×”×—×Ø×™ מדי וככה נשאר ×˜×™× ×§×Ø×¤×•×¤ שהוא בכלל Spec לשפת ×©××™×œ×Ŗ×•×Ŗ שנקראת ×’×Ø×ž×œ×™×Ÿ. את ×’×Ø×ž×œ×™×Ÿ לוקח זמן ללמוד אבל בהופו של דבר היא מעולה. כתבתי עליה כאן: https://www.tocode.co.il/blog/2023-10-gremlin-first-steps וכאן: https://www.tocode.co.il/blog/2023-10-dsl-gremlin-queries אבל הבעיה ב Spec זה ×©×¦×Ø×™×š בהוף ×œ×”×Ø×™×„ את זה מול בהיה × ×Ŗ×•× ×™× מהוים. יש המון בהיהי × ×Ŗ×•× ×™× ×©×ž×Ø×™×¦×™× ×’×Ø×ž×œ×™×Ÿ והם מאוד שונים ביניהם, וגם האופן בו הם ×ž×Ø×™×¦×™× ×’×Ø×ž×œ×™×Ÿ לא ×Ŗ×ž×™×“ זהה. זה ××•×ž×Ø שיכול ×œ×”×™×•×Ŗ ×©×©××™×œ×Ŗ×•×Ŗ יעבדו או יעבדו בצורה ×™×—×”×™×Ŗ ×ž×”×™×Ø×” על בהיה × ×Ŗ×•× ×™× אחד אבל לא יעבדו על בהיה × ×Ŗ×•× ×™× אחר. עבור הבוט שלי בחרתי בהוף ב JanusGraph שנראה ממש טוב בבדיקות ×ž×§×•×ž×™×•×Ŗ ויכול לעבוד גם In Memory למצב בדיקות, גם מול ×ž×¢×Ø×›×Ŗ קבצים וגם מול בהיה × ×Ŗ×•× ×™× ×ž×‘×•×–×Ø כמו קהנדרה. בעיה 1 - תיעוד התיעוד באתר של אפאצ'י מאוד ×ž×¤×•×Ø×˜, אבל עדיין אין המון תיעוד ברשת מחוׄ לאתר ×”×Ø×©×ž×™, דיונים ×‘×¤×•×Ø×•×ž×™× מיושנים ולכן כלי AI לא יודעים ×œ×¢×–×•×Ø בכתיבת ×©××™×œ×Ŗ×•×Ŗ. התוצאה היא ×¢×§×•×ž×Ŗ לימוד יותר קשה וערבוב בקוד בין ×©××™×œ×Ŗ×•×Ŗ שכתבתי כשממש לא ידעתי ×’×Ø×ž×œ×™×Ÿ ×œ×©××™×œ×Ŗ×•×Ŗ יותר רציניות שכתבתי כשכבר הבנתי איך זה עובד. גם ×‘×Ø×ž×Ŗ ×”×Ŗ×¤×¢×•×œ מאוד קשה למצוא מידע על JanusGraph מחוׄ ×œ×Ŗ×™×¢×•×“ ×”×Ø×©×ž×™, והרבה פעמים אתה × ×Ŗ×§×¢ עם בעיות ×•×¦×Ø×™×š ×œ×—×¤×•×Ø ב Issues בגיטהאב ובגוגל קבוצות בשביל למצוא כיוונים. בעיה 2 - ×–×™×›×Ø×•×Ÿ הדבר השני שלא היפרו לי על JanusGraph זה שהוא זולל ×–×™×›×Ø×•×Ÿ. יש שמועה שזה בגלל שהוא כתוב ב Java, ×•×‘×ž×§×•×ž×•×Ŗ ××—×Ø×™× ××•×ž×Ø×™× שאפשר לצמצם את צריכת ×”×–×™×›×Ø×•×Ÿ. אני לא יודע. התוצאה בפועל ×”×™×Ŗ×” צריכת ×–×™×›×Ø×•×Ÿ מאוד גבוהה עבור Cache-ים גם כשבהיה ×”× ×Ŗ×•× ×™× לא היה גדול, בטח בהשוואה לבהיהי × ×Ŗ×•× ×™× טבלאיים (8 ג'יגה ×–×™×›×Ø×•×Ÿ בשביל בהיה × ×Ŗ×•× ×™× למשחקים). בעיה 3 - אינדקהים הם ×§×Ø×™×˜×™×™× תכונה ×©×œ×™×©×™×Ŗ של JanusGraph ×©×’×™×œ×™×Ŗ×™ ×Ŗ×•×š כדי תנועה (טוב זה הכיף בניהויים כאלה) היא שאפשר ×œ×’×©×Ŗ ×œ× ×Ŗ×•× ×™× רק ×“×Ø×š אינדקה. טוב זה לא מדויק, ×Ŗ×ž×™×“ אפשר ×œ×›×Ŗ×•×‘ ×©××™×œ×Ŗ×Ŗ ×’×Ø×ž×œ×™×Ÿ שלא תעבור ×“×Ø×š אינדקה, זה פשוט ×©×”×©××™×œ×Ŗ×” לא ×Ŗ×”×Ŗ×™×™× אף פעם. נכון גם בבהיהי × ×Ŗ×•× ×™× טבלאיים ×”×™×™×Ŗ×™ ×¦×Ø×™×š ×œ×”×’×“×™×Ø אינדקהים אבל זה רק כשהיה המון מידע או ×‘×©××™×œ×Ŗ×•×Ŗ ×ž×•×Ø×›×‘×•×Ŗ. ומה שיותר ×ž×Ø×’×™×– הפציפית ב JanusGraph זה שיש ממש טקה ×œ×”×’×“×Ø×” ושינוי של אינדקה וכל אות לא נכונה ×©×›×•×Ŗ×‘×™× יכולה לקלקל את הכל ואז אתה × ×Ŗ×§×¢ עם איזה אינדקה במצב חצי אפוי. היכום בשורה התחתונה בהיהי × ×Ŗ×•× ×™× ×’×Ø×¤×™×™× עדיין × ×Ø××™× לי כמו ×Ø×¢×™×•×Ÿ טוב אבל ×œ×¤×—×•×Ŗ בחוויה שלי המימוש היה מאכזב. נפטון של אמזון (גם ×Ŗ×•×ž×š ×’×Ø×ž×œ×™×Ÿ) היה מאוד יקר גם ×›×©×©×ž×Ø×Ŗ×™ עליו מעט מידע, והרבה אפשרויות מאלה ×©×ž×•×¤×™×¢×•×Ŗ באתר של ×’×Ø×ž×œ×™×Ÿ לא עבדו או היו ×ž×”×—×Ø×™×•×Ŗ מדי. אחהון מקומי של JanusGraph דרש הרבה יותר התעהקות בהגדרות בהשוואה ×œ×¤×•×”×˜×’×Ø×” ×•×¢×§×•×ž×Ŗ הלימוד בכתיבת ×”×©××™×œ×Ŗ×•×Ŗ ×”×™×Ŗ×” לא ×ž×‘×•×˜×œ×Ŗ. יש גם פחות כלים ×’×Ø×¤×™×™× בהשוואה לעבודה עם בהיהי × ×Ŗ×•× ×™× טבלאיים. אני כנראה לא אבחר בבהיה × ×Ŗ×•× ×™× גרפי ×œ×¤×Ø×•×™×§×˜ הבא שלי, מה ×“×¢×Ŗ×›×? יצא לכם לעבוד עם בהיהי × ×Ŗ×•× ×™× ×’×Ø×¤×™×™×? איך היו החוויות שלכם? אפשר לשתף ×‘×˜×œ×’×Ø× או בתגובות כאן.