Node Master
امروز درمورد Duck Typing صحبت میکنیم. این موضوع مربوط به رفتار زبان های dynamic type میباشد. البته این تکنیک در زبان هایی static type هم در حالت های خاصی استفاده میشود. برای درک این موضوع با مثال در #Python شروع میکنیم. class Duck: def fly(self): …
قبلا درمورد Type Predict ها در #TypeScript صحبت کردیم از این لینک یک مطالعه کنید
https://t.iss.one/NodeMaster/90
و این که یک قسمت گفتیم که دو دیدگاه برای فیکس کردن همچین crash هایی در Runtime وجود دارد.
- Easier to ask for forgiveness than permission (EAFP)
- Look before you leap (LBYL)
قبل از این که درمورد این دو دیدگاه صحبت کنیم باید بگم که هرکدوم از این ها در یک زبان هایی مرسوم هست. به عنوان مثال در #Python نماد کد تمیز استفاده از EAFP و در #Javascript باید از LBYL استفاده کرد.
خودتون یکم برید راجع به این دوتا مطالعه کنید و بنظرتون بگید که Type Predict ها در #TypeScript از کدوم از این استایل ها استفاده میکنن؟
https://t.iss.one/NodeMaster/90
و این که یک قسمت گفتیم که دو دیدگاه برای فیکس کردن همچین crash هایی در Runtime وجود دارد.
- Easier to ask for forgiveness than permission (EAFP)
- Look before you leap (LBYL)
قبل از این که درمورد این دو دیدگاه صحبت کنیم باید بگم که هرکدوم از این ها در یک زبان هایی مرسوم هست. به عنوان مثال در #Python نماد کد تمیز استفاده از EAFP و در #Javascript باید از LBYL استفاده کرد.
خودتون یکم برید راجع به این دوتا مطالعه کنید و بنظرتون بگید که Type Predict ها در #TypeScript از کدوم از این استایل ها استفاده میکنن؟
Telegram
Node Master
یکی از قابلیت های خیلی خوب #typescript که خیلی کم استفاده میشه "type predicate" هست. به این شکل هست که شما در runtime میتونید یک interface رو valid کنید. همونطور که میدونید interface ها در typescript کلا در کد transpile نمیشوند و معمولا اکثرا با استفاده از…
👍1
همیشه دنبال یک معادل مناسب برای #Python Beautiful Soup در اکوسیستم #NodeJS بودم که نخوام با headless browser ها scrap انجام بدم. امروز این پکیج رو پیدا کردم شما هم اگر دوست داشتید یک چک کنید.
https://www.npmjs.com/package/cheerio
https://www.npmjs.com/package/cheerio
یکی از نقاط ضعفی که در #JavaScript وجود داره نبود استاندارد Error های مناسب طبق یک class hierarchy خوب مثل #Java یا #Python هست. حالا در #NodeJS سعی بر این شده که به این وضعیت رسیدگی بشه و وضعیت این Error ها به نسبت خود vanilla js خیلی بهتر هست.
در جهت همین موضوع یکی از Error های خیلی مهم در #NodeJS در حقیقت SystemError ها هستن. اگر دوست دارید درمورد سیستم عامل بیشتر بدونید این Error class شما رو یک خورده به سیستم عامل نزدیک تر میکنه. حالا سوال پیش میاد که SystemError چیست؟ اگر برنامه شما درخواستی داشته باشه از سیستم عامل ولی به هر دلیلی محدودیت هایی وجود داشته باشه #NodeJS با SystemError به شما اطلاع میده.
به این کد دقت کنید. ما در اینجا سعی میکنیم که یک فایلی رو از روی دیسک بخونیم که اصلا این فایل وجود نداره. در حقیقت داریم از سیستم عامل درخواست open syscall داریم که فایل رو بخونه یا ایجاد کنه ( در صورت استفاده از flag مناسب برای syscall که اینجا ست نکردیم) با توجه به این مثال به به محدودیت از سمت سیستم عامل میخوریم. و حاصل این کد یک SystemError هست. حالا در "node:util" یک فانکشن کمکی وجود داره که درصورتی که کد SystemError رو که در err.errorno میتونید بهش دسترسی داشته باشید بهش بدید. اسم که در اینجا ENOENT به من میده. این SystemError ها چون مربوط به سیستم عامل هست به زبان برنامه نویسی خاصی وابستگی ندارند و در همه زبان ها شما میتونید اینها رو ببینید.
#Tip
در جهت همین موضوع یکی از Error های خیلی مهم در #NodeJS در حقیقت SystemError ها هستن. اگر دوست دارید درمورد سیستم عامل بیشتر بدونید این Error class شما رو یک خورده به سیستم عامل نزدیک تر میکنه. حالا سوال پیش میاد که SystemError چیست؟ اگر برنامه شما درخواستی داشته باشه از سیستم عامل ولی به هر دلیلی محدودیت هایی وجود داشته باشه #NodeJS با SystemError به شما اطلاع میده.
import fs from "node:fs/promises";
import util from "node:util";
try {
await fs.readFile("./invalid-file.txt");
} catch (err) {
console.log(err);
console.log(util.getSystemErrorName(err.errno));
}
به این کد دقت کنید. ما در اینجا سعی میکنیم که یک فایلی رو از روی دیسک بخونیم که اصلا این فایل وجود نداره. در حقیقت داریم از سیستم عامل درخواست open syscall داریم که فایل رو بخونه یا ایجاد کنه ( در صورت استفاده از flag مناسب برای syscall که اینجا ست نکردیم) با توجه به این مثال به به محدودیت از سمت سیستم عامل میخوریم. و حاصل این کد یک SystemError هست. حالا در "node:util" یک فانکشن کمکی وجود داره که درصورتی که کد SystemError رو که در err.errorno میتونید بهش دسترسی داشته باشید بهش بدید. اسم که در اینجا ENOENT به من میده. این SystemError ها چون مربوط به سیستم عامل هست به زبان برنامه نویسی خاصی وابستگی ندارند و در همه زبان ها شما میتونید اینها رو ببینید.
#Tip
👍13
اگر تا حالا فکر کردین که چطور فریمورک ها رو برای ما developer های عادی توسعه میدن جواب شما یک magic هست به اسم #Metaprogramming . این کار مثل برنامه نویسی معمولی که ما انجام میدیم تکنیک های مختلف داره که یکی از اونها رو در این پست باهم برسی کردیم.
https://t.iss.one/NodeMaster/115
البته لازم به ذکر هست یکسری Pattern به صورت کلی وجود داره که بین زبان های مختلف مشترک هست و به نوعی پیاده سازی های مختلف ازش دیده میشه و البته یکسری زبان ها هم یکسری تکنیک های مخصوص به خودشون رو هم دارن که اون ها رو خاص تر میکنه.
حالا یکی از این جادو های کاربردی #Metaprogramming این هست که اگر یک Instance از یک Object داریم که یک Parrent Class داره چطور فقط و فقط متوجه بشیم که چه Attr هایی مخصوص به اون Child Class هست و Attr های Parrent رو نادیده بگیریم. و جواب این سوال خیلی سادس :
در #JavaScript با استفاده از Object.getOwnPropertyNames و Reflect.ownKeys(myObj) میتونیم متوجه بشیم که کدام Atter ها مربوط به Instnace ما یعنی myObj هستند. به این خاطر هست که Atter های Parrent یعنی x و y رو کامل نادیده گرفته میشه و فقط در name رو ما به عنوان Attr میبینم که مستقیما روی Child Instance ما تعریف شده و نه روی Parrent. شاید این مثال یکم پیچیده باشه بخاطر ماهیت Object ها در #JavaScript هست. همین رو اگر بخوایم در #Python برسی کنیم شاید یکم قابل درک تر باشه و البته مثال های دیگ هم در #JavaScript میشه زد ولی خب به نظرم بهتره بزاریم برای کنجکاوی خودتون.
یک نکته خیلی جذاب کلا خارج از بحث که به نظرم ارزش توجه کردن داره استفاده از set برای رسیدن به نتیجه ای شبیه به مثال #JavaScript هست. و اینجا به عنوان مثال مستقیم یکی از کاربرد های Set Object و Set theory رو مستقیم و خیلی کوچیک میبینید.
نکته ای که خیلی مهم باید توجه بشه این هست که بین تکنیک استفاده از ownKeys و getOwnPropertyNames تفاوت هایی وجود داره که اگر استقبال بشه عمیق تر وارد این موضوع میشیم.
#Tip
https://t.iss.one/NodeMaster/115
البته لازم به ذکر هست یکسری Pattern به صورت کلی وجود داره که بین زبان های مختلف مشترک هست و به نوعی پیاده سازی های مختلف ازش دیده میشه و البته یکسری زبان ها هم یکسری تکنیک های مخصوص به خودشون رو هم دارن که اون ها رو خاص تر میکنه.
حالا یکی از این جادو های کاربردی #Metaprogramming این هست که اگر یک Instance از یک Object داریم که یک Parrent Class داره چطور فقط و فقط متوجه بشیم که چه Attr هایی مخصوص به اون Child Class هست و Attr های Parrent رو نادیده بگیریم. و جواب این سوال خیلی سادس :
const myPrototype = { x: 1, y: 2 }; // Parrent
const myObj /* Child */ = Object.create(myPrototype);
myObj.name = "point"; // Instance Prop
console.log(Object.getOwnPropertyNames(myObj)); // [ 'name' ]
console.log(Reflect.ownKeys(myObj)); // [ 'name' ]
console.log("x in myObj :", "x" in myObj);در #JavaScript با استفاده از Object.getOwnPropertyNames و Reflect.ownKeys(myObj) میتونیم متوجه بشیم که کدام Atter ها مربوط به Instnace ما یعنی myObj هستند. به این خاطر هست که Atter های Parrent یعنی x و y رو کامل نادیده گرفته میشه و فقط در name رو ما به عنوان Attr میبینم که مستقیما روی Child Instance ما تعریف شده و نه روی Parrent. شاید این مثال یکم پیچیده باشه بخاطر ماهیت Object ها در #JavaScript هست. همین رو اگر بخوایم در #Python برسی کنیم شاید یکم قابل درک تر باشه و البته مثال های دیگ هم در #JavaScript میشه زد ولی خب به نظرم بهتره بزاریم برای کنجکاوی خودتون.
class Parrent:
def __init__(self) -> None:
self.x = 1
self.y = 2
class Child(Parrent):
def __init__(self) -> None:
super().__init__()
self.name = "point"
myObj = Child()
parrentAttrs = set(dir(Parrent()))
childAtters = set(dir(Child()))
print(childAtters.difference(parrentAttrs))
یک نکته خیلی جذاب کلا خارج از بحث که به نظرم ارزش توجه کردن داره استفاده از set برای رسیدن به نتیجه ای شبیه به مثال #JavaScript هست. و اینجا به عنوان مثال مستقیم یکی از کاربرد های Set Object و Set theory رو مستقیم و خیلی کوچیک میبینید.
نکته ای که خیلی مهم باید توجه بشه این هست که بین تکنیک استفاده از ownKeys و getOwnPropertyNames تفاوت هایی وجود داره که اگر استقبال بشه عمیق تر وارد این موضوع میشیم.
#Tip
Telegram
Node Master
خب first class function یعنی چی؟
به این موضوع هست که شما میتونید با function ها مثل بقیه object ها رفتار کنید. یعنی در متغیر ذخیرشون کنید یک لیستی از function ها داشته باشید و یا حتی در runtime فانکشن جدید بسازید و return کنید.
این موضوع خیلی نکته قوی هست…
به این موضوع هست که شما میتونید با function ها مثل بقیه object ها رفتار کنید. یعنی در متغیر ذخیرشون کنید یک لیستی از function ها داشته باشید و یا حتی در runtime فانکشن جدید بسازید و return کنید.
این موضوع خیلی نکته قوی هست…
👍8
من شخصا به عنوان یک #Python Hater دو آتیشه هستم.
ولی یک چیزی داره و عجیب خوب هست. حداقل من تا حالا شبیهش رو داخل هیچ اکوسیستم دیگه ای ندیدم و اگر شبیهش رو میشناسید معرفی کنید خوشحال میشم.
این ویژگی خیلی واقعا خفن pickle std برای #Python هست. در حقیقت pickle یک serialization format مثل #JSON هست و مثل #Protobuf یک فرمت binaray هست. حالا سوال پیش میاد چه نکته ای داره.
شما به pickel هر object در اکوسیستم #Python رو میتونید serialize کنید. هر Object با تمام پیچدگی ها custom که داره. بزارید با مثال توضیح بدم.
تصور کنید یک JSON دارید و اون رو میخواید map کنید به یک class و خب معمولا با Factory ها و به شکل های مختلف این اتفاق میافته.
همه چی خیلی منطقی کار میکنه در این سناریو. نکته جالب که اینجا و توجه بهش جالبه این هست که در اینجا به صورت ذاتی هیچ metadata وجود نداره که مشخص بشه مقدار runTimeInput واقعا از جنس User هست و معمولا با استفاده از validation های مختلف و factory متد ها باید مشخص کنیم. اگر بخوایم یک سناریو دیگ رو برسی کنیم که یکم پیچیده تر باشه. شما به هردلیل منطقی یا غیرمنطقی تصمیم داری یک function که در نهایت یک object هست رو serialize کنید. چطور این کار میکنید؟
باتوجه به این که در #JSON به طور کلی هیچ طوره فرمت استانداردی وجود نداره برای این کار منطقی هست کد بالا کار نکنه. ( البته با trick همین کد بالا رو میتونید کاری کنید که بشه ولی کاری به اون سناریو نداریم :) )
یک سناریو پیچیده تر اینه که شما یک object داشته باشید که property descriptor های اون رو دست کاری کردین چطور میخواین بدون ست کردن flag یا نشانه در هنگام serialize کردن و بعد از دریافت همون object متوجه بشید که property descriptor رو چطور باید ست کنید.
کلا بخوام خلاصه و جمع بندی کنم هرچیزی که مختص object هست که در runtime وجود داره مثل انواع reflection ها و property descriptor و method ها و ... .
اینجا هست که pickel خودش رو نشون میده.
در اینجا شما هر جسم قابل لمسی رو در #Python میتونید serialize کنید و مستقیم با خوندن همون data یک object قابل لمس در runtime با تمام metadata ها دریافت کنید. از class گرفته تا یک gatter method که با decorator هست تا انواع magic method ها یا به قول #Pythonic ها dunder method.
از همه جالب تر اون بخش آخر هست که یک Python Descriptor رو هم کنار object های User گذاشتیم و میبینیم اون هم به صورت کامل میبینیم. اگر بخوام خلاصه در یک جمله توضیح بدم رسما با اینکار انگار از یک object دارید فایل exe میسازید به جای یک برنامه بزرگ!
نکته بعدی این که این pickel استاندارد مربوط به کد های python هست و جای دیگ تقریبا میشه گفت کاربردی نداره.
https://docs.python.org/3/library/pickle.html
ولی یک چیزی داره و عجیب خوب هست. حداقل من تا حالا شبیهش رو داخل هیچ اکوسیستم دیگه ای ندیدم و اگر شبیهش رو میشناسید معرفی کنید خوشحال میشم.
این ویژگی خیلی واقعا خفن pickle std برای #Python هست. در حقیقت pickle یک serialization format مثل #JSON هست و مثل #Protobuf یک فرمت binaray هست. حالا سوال پیش میاد چه نکته ای داره.
شما به pickel هر object در اکوسیستم #Python رو میتونید serialize کنید. هر Object با تمام پیچدگی ها custom که داره. بزارید با مثال توضیح بدم.
تصور کنید یک JSON دارید و اون رو میخواید map کنید به یک class و خب معمولا با Factory ها و به شکل های مختلف این اتفاق میافته.
class User {
constructor(name) {
this.name = name;
}
static FromJsonString(input) {
const result = JSON.parse(input);
return new User(result.name);
}
}
const runTimeInput = '{"name":"imanhpr"}';
const user = User.FromJsonString(runTimeInput);
console.log(user instanceof User);
console.log(user.name);همه چی خیلی منطقی کار میکنه در این سناریو. نکته جالب که اینجا و توجه بهش جالبه این هست که در اینجا به صورت ذاتی هیچ metadata وجود نداره که مشخص بشه مقدار runTimeInput واقعا از جنس User هست و معمولا با استفاده از validation های مختلف و factory متد ها باید مشخص کنیم. اگر بخوایم یک سناریو دیگ رو برسی کنیم که یکم پیچیده تر باشه. شما به هردلیل منطقی یا غیرمنطقی تصمیم داری یک function که در نهایت یک object هست رو serialize کنید. چطور این کار میکنید؟
function hello() {
console.log("hooo");
}
console.log(JSON.stringify(hello));باتوجه به این که در #JSON به طور کلی هیچ طوره فرمت استانداردی وجود نداره برای این کار منطقی هست کد بالا کار نکنه. ( البته با trick همین کد بالا رو میتونید کاری کنید که بشه ولی کاری به اون سناریو نداریم :) )
یک سناریو پیچیده تر اینه که شما یک object داشته باشید که property descriptor های اون رو دست کاری کردین چطور میخواین بدون ست کردن flag یا نشانه در هنگام serialize کردن و بعد از دریافت همون object متوجه بشید که property descriptor رو چطور باید ست کنید.
کلا بخوام خلاصه و جمع بندی کنم هرچیزی که مختص object هست که در runtime وجود داره مثل انواع reflection ها و property descriptor و method ها و ... .
اینجا هست که pickel خودش رو نشون میده.
import pickle
class NumberOne:
def __get__(self, obj, objtype=None) :
return 1
class User:
__name = "iman"
one = NumberOne()
@property
def name(self):
print("hello from getter")
return self.__name
def __eq__(self, value: object) -> bool:
if isinstance(value , User) and self.__name == value.__name:
return True
return False
def __str__(self) -> str:
return f'User(name={self.__name})'
def hello():
print("hello from function")
# instance sterilization
user_instance_bin = pickle.dumps(User())
run_time_user = pickle.loads(user_instance_bin)
print("user instanceof User :",isinstance(run_time_user , User))
print("user object :" , run_time_user)
print("equality check :" , run_time_user == User())
print("getter invocation :" , run_time_user.name)
# function sterilization
function_bin = pickle.dumps(hello)
run_timefn = pickle.loads(function_bin)
run_timefn()
# class sterilization
cls_bin = pickle.dumps(User)
runtime_cls = pickle.loads(cls_bin)
print("class check:" , issubclass(runtime_cls , User))
# << Exciting part >>
print("WTF:",run_time_user.one)
در اینجا شما هر جسم قابل لمسی رو در #Python میتونید serialize کنید و مستقیم با خوندن همون data یک object قابل لمس در runtime با تمام metadata ها دریافت کنید. از class گرفته تا یک gatter method که با decorator هست تا انواع magic method ها یا به قول #Pythonic ها dunder method.
از همه جالب تر اون بخش آخر هست که یک Python Descriptor رو هم کنار object های User گذاشتیم و میبینیم اون هم به صورت کامل میبینیم. اگر بخوام خلاصه در یک جمله توضیح بدم رسما با اینکار انگار از یک object دارید فایل exe میسازید به جای یک برنامه بزرگ!
نکته بعدی این که این pickel استاندارد مربوط به کد های python هست و جای دیگ تقریبا میشه گفت کاربردی نداره.
https://docs.python.org/3/library/pickle.html
Python documentation
pickle — Python object serialization
Source code: Lib/pickle.py The pickle module implements binary protocols for serializing and de-serializing a Python object structure. “Pickling” is the process whereby a Python object hierarchy is...
👍5
یکی از نکات زیبا که درمورد #Deno و #JSR که وجود داره این هست که شما میتونید از پکیج های std دینو در #NodeJS استفاده کنید. همشون نه ولی به اکثرشون دسترسی دارید. به لینک زیر یک نگاهی بندازید و مشخصا میبینید که کدوم پکیج ها رو میتونید در پروژه #NodeJS خودتون استفاده کنید.
https://jsr.io/@std
به عنوان مثال پکیج @std/msgpack به پروژه خودمون اضافه میکنیم.
و بعد کد زیر رو با #NodeJS اجرا کنید.
حالا سوال پیش میاد که اصلا چرا همچین کاری باید کنیم. باتوجه به این که #JavaScript خودش std بزرگی مثل #Python یا #Java نداره گاهی اوقات نیاز به یک سری کدهای کمکی برای پروژه خودتون دارید و پکیج هایی مثل Lodash, es-toolkit کمک بزرگی کردن. اما حالا #Deno هم با این کار به اکوسیستم کمک بزرگی کرده و یک رنج از ابزار های کمکی که ممکنه در loadash و بقیه شبیهه بهش پیدا نکنید رو شاید اینجا پیدا کنید.
به عنوان مثال اگر پروژه کوچیکی دارید که فقط یک instance از server شما وجود داره استفاده از ابزاری مثل #Redis صرفا برای Cache زیاد منطقی نیست و خب در اکثرا اوقات یک Map ساده مشکل شما رو میتونه حل کنه. اگر ویژگی TTL هم بخواید داشته باشید خودتون میتونید پیاده سازی کنید با کمک Map ولی معمولا از پکیج node-cache در این سناریو استفاده میکنن. حالا یک گزینه دیگ داریم که مربوط به #Deno std هست.
https://jsr.io/@std/cache
این پکیج جدا از مثال بالا مدل های مختلف دیگ از cache رو در اختیار شما میزاره که نگاهی بندازید و جالبه.
https://jsr.io/@std
به عنوان مثال پکیج @std/msgpack به پروژه خودمون اضافه میکنیم.
npx jsr add @std/msgpack
و بعد کد زیر رو با #NodeJS اجرا کنید.
import * as msgpack from "@std/msgpack";
const data = { name: "node-master" };
const enc = msgpack.encode(data);
const dec = msgpack.decode(enc);
console.log(dec);
حالا سوال پیش میاد که اصلا چرا همچین کاری باید کنیم. باتوجه به این که #JavaScript خودش std بزرگی مثل #Python یا #Java نداره گاهی اوقات نیاز به یک سری کدهای کمکی برای پروژه خودتون دارید و پکیج هایی مثل Lodash, es-toolkit کمک بزرگی کردن. اما حالا #Deno هم با این کار به اکوسیستم کمک بزرگی کرده و یک رنج از ابزار های کمکی که ممکنه در loadash و بقیه شبیهه بهش پیدا نکنید رو شاید اینجا پیدا کنید.
به عنوان مثال اگر پروژه کوچیکی دارید که فقط یک instance از server شما وجود داره استفاده از ابزاری مثل #Redis صرفا برای Cache زیاد منطقی نیست و خب در اکثرا اوقات یک Map ساده مشکل شما رو میتونه حل کنه. اگر ویژگی TTL هم بخواید داشته باشید خودتون میتونید پیاده سازی کنید با کمک Map ولی معمولا از پکیج node-cache در این سناریو استفاده میکنن. حالا یک گزینه دیگ داریم که مربوط به #Deno std هست.
https://jsr.io/@std/cache
این پکیج جدا از مثال بالا مدل های مختلف دیگ از cache رو در اختیار شما میزاره که نگاهی بندازید و جالبه.
JSR
👍5
درود دوستان ارادتتتت.
خیلی وقت بود میخواستم این ویدیو رو بگیرم. روزی که من #Python گذاشتم کنار و حرفه ای شروع به کد زدن #JavaScript و #NodeJS کردم همیشه هروقت باکسی بحث برنامه نویسی میشد من این رو میگفتم که جای یک چیزی مثل Context Manager مثل پایتون در اکوسیستم #JavaScript واقعا خالی هست. وقتی #TypeScript ورژن 5.2 منتشر شد و این syntax رو برای بار اول دیدم واقعا خوشحال شدم
در این ویدیو به Explicit Resource Management در زبان های برنامه نویسی #python , #golang و #cpp میکنیم. با یک پترن خیلی قدیمی به اسم RAII پترن آشنا میشیم و در نهایت میرسیم به ارتباط RAII پترن در C++ در #Typescript .
این ویدیو قرار هست در دو پارت منتشر بشه و پارت دوم رو کامل درمورد مثال های عملی #Typescript گذاشتیم و تمرکز ویدیو اول هم بیشتر نگاه به زبان های دیگر و برسی این موضوع که چرا به "using" نیاز داریم.
https://youtu.be/0CG_WA6Yu9o?si=QYunevpiEyWp6gWW
خیلی وقت بود میخواستم این ویدیو رو بگیرم. روزی که من #Python گذاشتم کنار و حرفه ای شروع به کد زدن #JavaScript و #NodeJS کردم همیشه هروقت باکسی بحث برنامه نویسی میشد من این رو میگفتم که جای یک چیزی مثل Context Manager مثل پایتون در اکوسیستم #JavaScript واقعا خالی هست. وقتی #TypeScript ورژن 5.2 منتشر شد و این syntax رو برای بار اول دیدم واقعا خوشحال شدم
async function main() {
using resource1 = getResource()
await using resource2 = await getResource()
}در این ویدیو به Explicit Resource Management در زبان های برنامه نویسی #python , #golang و #cpp میکنیم. با یک پترن خیلی قدیمی به اسم RAII پترن آشنا میشیم و در نهایت میرسیم به ارتباط RAII پترن در C++ در #Typescript .
این ویدیو قرار هست در دو پارت منتشر بشه و پارت دوم رو کامل درمورد مثال های عملی #Typescript گذاشتیم و تمرکز ویدیو اول هم بیشتر نگاه به زبان های دیگر و برسی این موضوع که چرا به "using" نیاز داریم.
https://youtu.be/0CG_WA6Yu9o?si=QYunevpiEyWp6gWW
YouTube
کلمه کلیدی "using" در #typescript و #javascript - پارت اول
درود دوستان.
در این ویدیو با هم دیگه یاد میگیرم که چرا وجود کلمه کلیدی "using" در #javascript میتونه برای ما نجات بخش باشه.
البته در این ویدیو بیشتر تمرکز به برسی تاریخچه و رویکرد زبان های برنامه نویسی مختلف دیگر مثل #golang , #cpp , #python در این سناریو…
در این ویدیو با هم دیگه یاد میگیرم که چرا وجود کلمه کلیدی "using" در #javascript میتونه برای ما نجات بخش باشه.
البته در این ویدیو بیشتر تمرکز به برسی تاریخچه و رویکرد زبان های برنامه نویسی مختلف دیگر مثل #golang , #cpp , #python در این سناریو…
👍13
درود دوستان.
قبلا که #python کد میزدم یک پکیج داشت به اسم isort که import ها رو خیلی تر تمیز sort میکرد. همیشه دنبال یک پکیج خوب بودم برای #typescript که همچین کاری رو انجام بده تا بلاخره دیروز یک پکیح خوب پیدا کردم که میتونید به عنوان config prettier استفاده کنید.
البته package های دیگ هم هستن ولی این خیلی برای من راحت تر بود. فکر کنم eslint هم همچین چیزی داشته باشه ولی فرصت نشده تست کنم.
https://www.npmjs.com/package/prettier-plugin-organize-imports
قبلا که #python کد میزدم یک پکیج داشت به اسم isort که import ها رو خیلی تر تمیز sort میکرد. همیشه دنبال یک پکیج خوب بودم برای #typescript که همچین کاری رو انجام بده تا بلاخره دیروز یک پکیح خوب پیدا کردم که میتونید به عنوان config prettier استفاده کنید.
البته package های دیگ هم هستن ولی این خیلی برای من راحت تر بود. فکر کنم eslint هم همچین چیزی داشته باشه ولی فرصت نشده تست کنم.
https://www.npmjs.com/package/prettier-plugin-organize-imports
👍7
درود دوستان امیدوارم حالتون خوب باشه. یک ویژگی خیلی کوچیک #Python داشت که من همیشه دلم میخواد داخل #NodeJS ببینم. این ویژگی خیلی وقته روی #Deno هست ( فکر کنم #BunJS هم داره ). واقعا جای خالیش رو من حس میکردم. و بلاخره این ویژگی رو به صورت Experimental در آپدیت 22.18 دیدیم که اضافه شد. برا این که وارد بحث بشیم دوست دارم با این کد پایتون شروع کنم.
توضیح کد خیلی ساده هست که با استفاده از این پترن میشه تشخیص داد آیا این بخش از code که داره اجرا میشه آیا import شده توسط یک ماژول دیگه یا ماژول اصلی هست که باهاش برنامه رو اجرا کردن؟ اگر ماژول اصلی باشه که برنامه رو run کردن فانکشن main رو اجرا میکنه برنامه وارد main routine خودش میشه. شاید فکر کنید داخل زبانی مثل #Python و #JavaScript اینکار احمقانه باشه باتوجه به این که هر expressionـی رو میتونیم داخل top level خودمون اجرا کنیم. پس مزیت این کار چیه؟ جواب این هست که باتوجه به این که ما برنامه رو مینویسیم خب ما میدونیم کجا main routine رو اجرا کنیم ولی تصور کنید روی یک code base بزرگ رفتین و دنبال entrypoint میگردید. در این سناریو میتونه به عنوان داکیومنتیشن مناسب باشه. یا زمانی بخواید کدی رو اجرا کنید که فقط و فقط اگر کسی اون ماژول رو import کرده باشه و ... . همین الان هم وقتی پروژه #NestJS دارید bootstrap function دقیقا داره نقش main routine رو بازی میکنه و شما حتما باید اون رو اجرا کنید که برنامتون اجرا بشه. معمولا داخل #NestJS همچین چیزی میبینیم
سناریویی رو در نظر بگیرد به هر دلیلی میخواید از این main.js یک چیزی رو import کنید( هرچند اگر همچین چیزی نیاز داشتید بهتره سعی کنید راه دیگه ای پیدا کنید ) و اگر شما این فایل رو import کنید داخل یک ماژول دیگه خب bootstrap اجرا میشه و ما این رو نمیخوایم. پس چیکار میتونیم کنیم؟
اینجا هست import.iss.oneta.main به کمک ما میاد حالا اگر شما مستقیما node main.js بزنید فانکشن bootstrap اجرا میشه ولی اگر از یک فایل دیگ مثل server.js داشته باشید و این فایل رو import کنید بخش else اجرا میشه و bootstrap هیچ وقت call نمیشه.
def main():
print("Hello From Main Function")
if __name__ == "__main__":
main()
توضیح کد خیلی ساده هست که با استفاده از این پترن میشه تشخیص داد آیا این بخش از code که داره اجرا میشه آیا import شده توسط یک ماژول دیگه یا ماژول اصلی هست که باهاش برنامه رو اجرا کردن؟ اگر ماژول اصلی باشه که برنامه رو run کردن فانکشن main رو اجرا میکنه برنامه وارد main routine خودش میشه. شاید فکر کنید داخل زبانی مثل #Python و #JavaScript اینکار احمقانه باشه باتوجه به این که هر expressionـی رو میتونیم داخل top level خودمون اجرا کنیم. پس مزیت این کار چیه؟ جواب این هست که باتوجه به این که ما برنامه رو مینویسیم خب ما میدونیم کجا main routine رو اجرا کنیم ولی تصور کنید روی یک code base بزرگ رفتین و دنبال entrypoint میگردید. در این سناریو میتونه به عنوان داکیومنتیشن مناسب باشه. یا زمانی بخواید کدی رو اجرا کنید که فقط و فقط اگر کسی اون ماژول رو import کرده باشه و ... . همین الان هم وقتی پروژه #NestJS دارید bootstrap function دقیقا داره نقش main routine رو بازی میکنه و شما حتما باید اون رو اجرا کنید که برنامتون اجرا بشه. معمولا داخل #NestJS همچین چیزی میبینیم
function bootstrap() {
// init app
}
bootstrap();سناریویی رو در نظر بگیرد به هر دلیلی میخواید از این main.js یک چیزی رو import کنید( هرچند اگر همچین چیزی نیاز داشتید بهتره سعی کنید راه دیگه ای پیدا کنید ) و اگر شما این فایل رو import کنید داخل یک ماژول دیگه خب bootstrap اجرا میشه و ما این رو نمیخوایم. پس چیکار میتونیم کنیم؟
function bootstrap() {
console.log("hello");
}
if (import.iss.oneta.main) {
bootstrap();
} else {
console.log("imported");
}اینجا هست import.iss.oneta.main به کمک ما میاد حالا اگر شما مستقیما node main.js بزنید فانکشن bootstrap اجرا میشه ولی اگر از یک فایل دیگ مثل server.js داشته باشید و این فایل رو import کنید بخش else اجرا میشه و bootstrap هیچ وقت call نمیشه.
👍14
ما Developer ها به Magic عادت داریم. بیشتر وقت ها کدی که مینویسیم فقط میخوایم کار کنه. اما چطور کار کردن اون کد خیلی اهمیتی نداره تا وقتی که کدمون کار میکنه. حالا چه به صورت جادویی کار کنه چه با جزئیات کامل بدونیم پشت پرده چخبر هست. گاها بعضی از این جادو ها اینقدر پیچیده و ترسناک به نظر میان که اصلا بهشون نزدیک نمیشیم. یکی از این Magic ها Promise ها در #JavaScript هست. اکثرا فکر میکنیم یک چیزی هست که داخل گوشت و وجود #JavaScript فرو رفته و به هیچ عنوان نمیشه تغییرش داد یا اگر هم بشه خیلی سخت هست. کاری به پیاده سازی اصلیش امروز نداریم. امروز بعد از این مقدمه طولانی میخواهیم باهم یاد بگیرم چطور یک Object بسازیم که شبیه به Promise عمل میکنه. یعنی میتونیم await کنیم اون رو با وجود این که اصلا اون Promise نیست و یک Object ساده هست. به این کد پایین دقت کنید.
معمولا اولین واکنش افراد به این تکه کد "WTF" هست. داستان از این قرار هست که خیلی قبل تر از این که Promise ها به صورت استاندارد وارد #JavaScript بشن پیاده سازی های مختلف ازش وجود داشته و هرکدوم implemention detail خاص خودشون رو داشتن ولی طی گذر زمان بلاخره رسیدن به این interface که الان داریم هر روز باهاش کار میکنیم ( تقریبا شبیه به وضعیت decorator ها و پروپزوال مربوط بهش ). بزارید یکم بیشتر وارد داستان بشیم.
برای این که بتونیم یک object رو await کنیم لزوما نیازی نداره حتما یک instance از Promise باشد. بلکه هر object که Promise-like باشد میتواند await بشود. این تعریف دقیقا تعریف Duck-typing هست که قبلا مفصل درموردش حرف زدیم. حالا سوال پیش میاد که Promise-like یعنی چی؟
- هر class که thanable interface را implement کند میتوان آن را await کرد.
پس میتونیم نتیجه بگیریم که همه Promise ها thenable هستند ولی همه thenable ها Promise نیستند.
حالا میرسیم که thanable interface چیست؟ در ساده ترین حالت دقیقا مثال بالا رو در نظر بگیرد. یک object یا class که then method رو که با دوتا argument که هردو callback هستن یکی برای وقتی که reject شده و یکی برای وقتی resolve میشه invoke میشود و ما میتونیم با اون دوتا رفتاری که Promise-like هست رو از خودمون نشون بدیم.
حالا این ویژگی به ما اجازه داده که پکیج های معروفی مثل promise-retry ببینیم یا حتی یکم تلاش کنیم به کمک Promise-like ها در ES5 بتونیم چیزی شبیه بهش رو داشته باشیم که البته این موضوع خودش یک بحث دیگس اگر دوست دارید نگاهی به promise-polyfill یا babel-polyfill بندازید.
این هم پست مربوط به duck typing به نظرم نگاهی بندازید:
https://t.iss.one/NodeMaster/128
const thenable = {
then(resolve, reject) {
setTimeout(() => resolve("Hello from thenable!"), 1000)
},
}
const txt = await thenable
console.log(txt)معمولا اولین واکنش افراد به این تکه کد "WTF" هست. داستان از این قرار هست که خیلی قبل تر از این که Promise ها به صورت استاندارد وارد #JavaScript بشن پیاده سازی های مختلف ازش وجود داشته و هرکدوم implemention detail خاص خودشون رو داشتن ولی طی گذر زمان بلاخره رسیدن به این interface که الان داریم هر روز باهاش کار میکنیم ( تقریبا شبیه به وضعیت decorator ها و پروپزوال مربوط بهش ). بزارید یکم بیشتر وارد داستان بشیم.
برای این که بتونیم یک object رو await کنیم لزوما نیازی نداره حتما یک instance از Promise باشد. بلکه هر object که Promise-like باشد میتواند await بشود. این تعریف دقیقا تعریف Duck-typing هست که قبلا مفصل درموردش حرف زدیم. حالا سوال پیش میاد که Promise-like یعنی چی؟
- هر class که thanable interface را implement کند میتوان آن را await کرد.
پس میتونیم نتیجه بگیریم که همه Promise ها thenable هستند ولی همه thenable ها Promise نیستند.
حالا میرسیم که thanable interface چیست؟ در ساده ترین حالت دقیقا مثال بالا رو در نظر بگیرد. یک object یا class که then method رو که با دوتا argument که هردو callback هستن یکی برای وقتی که reject شده و یکی برای وقتی resolve میشه invoke میشود و ما میتونیم با اون دوتا رفتاری که Promise-like هست رو از خودمون نشون بدیم.
حالا این ویژگی به ما اجازه داده که پکیج های معروفی مثل promise-retry ببینیم یا حتی یکم تلاش کنیم به کمک Promise-like ها در ES5 بتونیم چیزی شبیه بهش رو داشته باشیم که البته این موضوع خودش یک بحث دیگس اگر دوست دارید نگاهی به promise-polyfill یا babel-polyfill بندازید.
این هم پست مربوط به duck typing به نظرم نگاهی بندازید:
https://t.iss.one/NodeMaster/128
Telegram
Node Master
امروز درمورد Duck Typing صحبت میکنیم. این موضوع مربوط به رفتار زبان های dynamic type میباشد. البته این تکنیک در زبان هایی static type هم در حالت های خاصی استفاده میشود. برای درک این موضوع با مثال در #Python شروع میکنیم.
class Duck:
def fly(self):
…
class Duck:
def fly(self):
…
👍11