حفظ سازگاری عقبگرد با تکنیک PIMPL

اگر توسعه‌دهندهٔ یک کتابخانهٔ نرم‌افزاری به زبان ‪C++‬ (یا هر زبان native دیگری) هستید همیشه باید نکاتی رو مدنظر داشته باشید که کاربران کتابخانهٔ شما دچار مشکل نشوند. از جمله این اصول میشه به نسخه‌گذاری معنایی، طراحی API اصولی و حفظ سازگاری اشاره کرد. سازگاری مبحث بزرگ و پیچیده‌ای هست که یک نوشتهٔ مفصل‌تر میخواد. در این پست میخوام در مورد یکی از تکنیک‌های پراستفاده در C و ‪C++‬ بنویسم که به حفظ سازگاری عقبگرد در در سطح باینری کمک میکنه.

توابع سره در ‪C++‬

یکی از امکانات بهینه‌سازی که بین برنامه‌نویس‌های سی کمتر شناخته شده؛ امکان تعریف توابع به‌صورت سره هست. این امکان دامنهٔ گسترده‌ای از بهینه‌سازی‌ها رو امکان‌پذیر می‌کنه و حتماً باید جایی که کارایی مهم هست از این ویژگی استفاده کنید. در این پست به معرفی و بررسی اثر توابع سره می‌پردازم.

تقویم هجری خورشیدی در کیوت

برای ما ایرانی‌ها استفاده از تقویم فارسی در محیط کامپیوتری همیشه چالش‌برانگیز بوده. به‌طور سیستم‌های رایانه‌ای با درنظر داشتن امکان تغییر تقویم‌ها طراحی و توسعه پیدا نمی‌کنند و ما همیشه مجبوریم جای خالی تقویم رسمی کشور - هجری خورشیدی - رو با هک و روش‌های غیرمتعارف پر کنیم.

برای من همیشه نبود تقویم هجری شمسی در کیوت آزاردهنده بوده. وقتی می‌خواستم تاریخ رو داخل برنامه‌های ‪C++‬ نشون بدم؛ یا باید از ویجت‌هایی که خودم ساختم استفاده می‌کردم یا به تاریخ گرگورین (میلادی) بسنده می‌کردم. از نسخهٔ ۴٫۶ و دقیقاً بعد از زمانی که ترجمهٔ فارسی کیوت رو منتشر کردم، به فکر پیاده‌سازی تقویم رسمی کشور توی این فریم‌ورک بودم. متأسفانه اون روزها امکان پیاده‌سازی به دلایل محتلف وجود نداشت. با این حال اولین نمونه‌ها رو ساختم ولی به کیوت ۵ نرسید. کیوت ۵ داستان غم‌انگیز خودش رو داشت و با انتشار نسخهٔ نارس ۵٬۰٬۰ ؛ فرصتی که با تغییر نسخه از چهار به پنج به وجود آمده بود هم از دست رفت. اما بالأخره بعد از گذشت ۶ سال و فراموش شدن موضوع تونستم تقویم هجری خورشیدی رو برای کیوت ۵٫۱۰ پیاده‌سازی کنم. نسخهٔ نهایی همراه با کیوت ۵٫۱۴ در تاریخ ۲۱ آذر سال ۱۳۹۸ منتشر شد. این پست به چالش‌ها و روال توسعهٔ تقویم و نحوهٔ استفاده از API اختصاص داده شده.

نمونهٔ اجرا

محاسبهٔ ثابت‌های ریاضی

هیچ‌کدام از استانداردهای سی‌پلاس‌پلاس و یا سی عدد π را تعریف نکرده‌اند. بنابراین هر برنامه‌نویسی که قصد داشته باشه از توابع مثلثاتی یا آماری استفاده کنه مجبوره خودش π رو تعریف کنه. خوشبختانه فایل‌های سرآیند استاندارد عدد π رو تعریف کرده‌اند، (ثابت M_PI در هدر math.h رو ببینید) با این وجود استفاده از این ثابت و ثابت‌های دیگه بسیار خطرناک هست و برای کاربردهای دقیق باعث بروز خطاهای عددی خواهد شد.

مشکل نیم‌فاصله در KDE و روش حل آن

قبلاً در مورد باگ بسیار بدی که در کیوت به‌وجود آمده بود و روش حل آن نوشتم. این باگ باعث میشد امکان نوشتن نویسه‌های کنترلی مثل نیم‌فاصله و تغییر جهت به‌طور کامل از بین بره. (اگر از نیم‌فاصله استفاده نمی‌کنید و یا نمی‌دونید تغییر جهت متن چه اهمیتی داره حتماً نویسه‌های کنترلی و جهت‌دهی متون فارسی/انگلیسی رو بخونید)

الآن با گذشت چند ماه باگ مربوطه برطرف شده و با نسخهٔ 5.9.1 منتشر شده. (تغیرات گریت برای ماژول qtbase اینجا و برای ماژول qtdeclarative اینجا قابل مشاهده هستند) خوشبختانه برنامه‌های کیوت دیگه مشکل سابق رو ندارند و هم توی ماژول widgets و هم توی ماژول جدیدتر Qt Quick مشکل به‌طور کامل برطرف شده. خوب حداقل من این‌طور فکر می‌کردم!

برنامه‌نویسی شبکه در ویندوز/لینوکس: libcpnet

کارفرمای کاری که الان دارم انجام میدم اصرار داره که برنامه‌ش علاوه‌بر لینوکس روی ویندوز هم به‌خوبی اجرا بشه. مدیر من کاملاً این محدودیت رو پذیرفته و به کارفرما گفته که با سخت‌افزاری که مشخصاتش رو اعلام می‌کنیم و با مشخصات کارکردی که اعلام می‌کنیم، روی ویندوز هم می‌تونید برنامه رو اجرا کنید. خوب این تصمیم مشکلات بسیار بزرگی برای برنامه‌نویس به‌وجود میاره. ازجمله برنامه‌نویسی شبکه… این پست به بررسی این مشکلات و ارائهٔ یک راه حل خوب خواهد پرداخت (: اگر قصد دارید کدی بنویسید که هم روی ویندوز و هم روی سیستم‌عامل‌های واقعی بتونه از شبکه استفاده کنه حتماً ادامهٔ مطلب رو بخونید.

بدترین باگ کیوت!

کیوت به‌نظر من بهترین فریم‌ورک سی‌پلاس‌پلاس هست. یک کتابخانهٔ خیلی بزرگ با امکانات بسیار عالی و خوب که محیط کاری KDE به‌طور کامل برپایهٔ اون ساخته شده. اما از نسخهٔ 5.3 (ظاهراً) یک باگی به‌وجود آمده که زندگی رو برای ما خیلی سخت کرده: عدم امکان وارد کردن نویسه‌های کنترلی و نیم‌فاصله‌های چسبان و غیرچسبان! (قبلاً در مورد مورد نویسه‌های کنترلی و جهت‌دهی متون فارسی/انگلیسی نوشتم.) حوزهٔ تأثیر این باگ به قدری بزرگ و گسترده است که کار با محیط KDE رو برای ما غیرممکن کرده. تصور کنید که تقریباً هیچ جایی توی سیستم‌عامل و برنامه‌های کاربردی محیط دسکتاپ نتونید نویسه‌های کنترلی و فاصله‌ها رو تایپ کنید! توی این نوشته قصد دارم دلایل این باگ و روش برطرف کردنش و همچنین روش دور زدن اون رو توضیح بدم (: خوشبختانه روش فیکس خیلی ساده‌ست. و البته جای نگرانی نیست: نسخه‌های فیکس با کیوت 5.8.1 (اگر ریلیز بشه) و یا 5.9.0 (در هر صورت) منتشر میشن. منتها کسایی که نمی‌خوان تا اواسط 2018 صبر کنن که اون نسخه‌ها برای دبیان و اوبونتو بیاد، خودشون می‌تونن با این روشی که توضیح میدم پچ کنن (:

این بورد لعنتی

مدتی‌یه که برای انجام یه پروژهٔ صنعتی یه بورد Smart 210 به دستم رسیده. این بورد ساخت شرکت FriendlyARM هست که یه کمپانی چینی‌یه که سخت‌افزارهای ارزون‌قیمت صنعتی می‌سازه. مشخصات ظاهری‌ش خوب به نظر می‌رسه. با این وجود از لحاظ نرم‌افزاری یک فاجعه‌ست! این پست توضیحاتی در مورد طرز کار و بیشتر توضیح معایب این بورده. امیدوارم در آینده برای کسایی که می‌خوان باهاش کار کنن مفید باشه یا لااقل باعث باشه از خریدش منصرف بشن (:

بورد اصلی و پردازندهٔ Smart 210

کتابخانهٔ Dynamixel

مدتی هست که هم توی شبکه‌های اجتماعی و هم این‌جا فعالیتم خیلی کم شده. دلیلش پروژه‌ای هست که در حال حاضر وقت خیلی زیادی ازم می‌گیره و مجبورم به‌خاطرش مسافرت‌های طولانی رو برم و برگردم.

اما ماحصل یکی از این سفرها یک کتابخانهٔ جدید و بسیار خوشگل و مرتب شده به اسم libdynamixel. این کتابخانه یک API سطح بالا برای کنترل و استفاده از سروو موتورهای هوشمند داینامیکسل طراحی شده. این پست در مورد ویژگی‌های این کتابخانه است.

ارتباط میان‌زبانی

زبان مورد استفاده برای پیاده‌سازی یک ابزار، یکی از ویژگی‌های آن نیست.

دنیا پر از ابزارها و کتابخانه‌هایی هست که به‌دست برنامه‌نویسان مختلفی به‌زبان‌های مختلف نوشته شدن. بدون وجود این کتابخانه‌ها و ابزارها زندگی برای ما برنامه‌نویس‌ها (به‌دلایلی واضح) خیلی سخت می‌شد.

به عقیدهٔ من همه‌چیز باید همه‌جا برای همه‌کس قابل استفاده باشه. یعنی این که مثلاً این که من فلان کتابخانهٔ کاربردی و باحال رو با زبان ‪C++‬ پیاده‌سازی کردم نباید باعث بشه که یک برنامه‌نویس پایتون یا جاوا نتونه ازش استفاده کنه. حتا زبان‌هایی که دامنه و کاربرد مختلفی دارن باید پشتیبانی بشن. مثلاً یکی از ابزارهایی که ساختم در اصل به‌عنوان یک «حل‌کنندهٔ مسأله» برای کاربردهای پیشرفتهٔ هوش مصنوعی طراحی شده، و این‌چنین موضوعاتی معمولاً برای کاربردهای سیستمی و خاص‌منظوره استفاده میشن. اما هیچ دلیلی وجود نداره که یک برنامه‌نویس وب برای یک اپلیکیشن آنلاین نخواد از مدل‌سازی ارضای محدودیت برای حل یک سری مسائل داخل برنامه‌ش استفاده کنه، یا یک برنامه‌نویس اندرویید نخواد از سیستم‌های استنتاج فازی برای برنامه‌ش استفاده کنه. بنابراین وظیفهٔ منِ برنامه‌نویس است، که برای تمام زبان‌هایی که می‌تونم، رابط (=>interface)های بومی (=>native) فراهم کنم تا همه بتونن از ابزارم استفاده کنن.

توی این پست نحوهٔ ایجاد رابط برای زبان‌های مختلف رو توضیح میدم. طبق این روش ساده، میشه به‌راحتی برای کتابخانه‌های ‪C++‬ رابط‌هایی برای تمام زبان‌های دیگه پیاده‌سازی کرد.

پادشاه و استادِ بزرگ

روزی پادشاهی استادِ بزرگ را نزد خویش فراخواند و به او گفت: ای حکیم دانا!‌ به من چیزی بیاموز که در غمگینی مراخوشحال کرده و دوران خوشی مرا غمگین کند. استادِ بزرگ به وی گفت: ای پادشاه کبیر! هرگاه در چنگال غم و اندوه گرفتار شدی، به‌خاطر بیاور که غمِ دنیا می‌گذرد؛ آن‌گاه شاد خواهی شد. و هرگاه در روزگار بر وفق مراد بود به‌خاطر بیاور که این خوشی پایدار نیست و آنگاه اندوهگین خواهی شد.

توسعهٔ میان‌نسخه‌ای

سال گذشته توی وبلاگ انگلیسی‌م پستی در مورد توسعهٔ نرم‌افزار بین نسخه‌های مختلف کیوت نوشته بودم که مدت‌هاست وقت نکردم ترجمه‌ش کنم. این پست در مورد توضیح یک روش کارامد برای کدنویسی بین نسخهٔ ۴ و ۵ کیوت هست اما میشه کلیت‌ش رو به تمام چارچوب‌ها و کتابخانه‌هایی که در یک بازهٔ زمانی چند نسخه دارند، تعمیم داد. برای برنامه‌هایی که به‌طور طولانی‌مدت پشتیبانی میشن، این شرایط خیلی زیاد پیش میاد.فرض کنید برنامه‌ای نوشته میشه که قراره با ZMQ نسخهٔ ۲ کار کنه. بعد از گذشت چند سال توسعه‌دهنده‌ها به این نتیجه می‌رسن که باید نسخهٔ ۳ پشتیبانی بشه و پکیج‌هایی از کدهای کامپایل شده با نسخهٔ ۳ تهیه بشه. بنابراین بهترین راه حل نوشتن کدی هست که با هر دو نسخه کامپایل بشه. برای ابزارهایی که کتابخانه نیستند هم همین صادق هست. مثلاً اسکریپتی که قراره با پایتون ۲ کار کنه اما باید با پایتون ۳ هم کار کنه.

توسعهٔ چندسکویی

دوست دارم برنامه‌ها و کتابخونه‌هام روی پلتفرم‌های مختلف اجرا بشن. هرچه بیشتر بهتر! البته همیشه هدف اصلی همیشه لینوکس و سیستم‌های شبه‌یونیکس هستند. با این حال بدم نمیاد که عملکرد مشابهی رو برای ویندوز و اندرویید، شاید هم مک‌اواس فراهم کنم. در واقع پلتفرم نباید یک محدودیت برای استفاده از نرم‌افزار باشه. مجموع این‌ها ما رو به ایدهٔ توسعهٔ چندسکویی می‌رسونه. متأسفانه این کار چندان ساده هم نیست. استاندارد پذیرفته‌شده‌ای برای APIهای سیستم‌عامل‌ها وجود نداره. همچنین هیچ الگوی کلی‌ای برای عملیات سیستم‌عامل موجود نیست. توسعه‌دهنده‌ها باید با درنظر داشتن تمام نیازمندی‌های چندسکویی کد بنویسند.

توی این پست، تجربهٔ شخصی خودم رو در مورد توسعهٔ چندسکویی پروژهٔ AIT می‌نویسم. توی اون پروژه به مشکلات زیادی برخوردم و تعدادی‌شون رو حل کردم. این نوشته یک چک‌لیست ساده برای کسایی که می‌خوان توسعهٔ چندسکویی انجام بدن فراهم می‌کنه که بتونن از مشکلات توسعهٔ چندسکویی با زبان‌های ‏‪C/C++‬ پیشگیری کنن. رفتیم که بریم :)

چپ‌به‌راست، راست‌به‌چپ و Unicode BiDi

حتماً تا به‌حال براتون پیش اومده که وسط یه متن فارسی، یک متن انگلیسی می‌نویسید و همه‌چیز قاطی میشه. مخصوصاً توی محیط‌های Plain Text (یعنی محیط‌های متنی‌ای که شما کنترلی روی استایل و پاراگراف ندارید. مثل gedit یا kate یا مثلاً notepad). خیلی زود متوجه خواهید شد که روش ساده‌ای برای نوشتن کاراکترهایی که نه راست‌به‌چپ هستن و نه چپ‌به‌راست هستن، وجود نداره (در ادامه میگم که جهت یک کاراکتر یعنی چی). توی این پست می‌خوام روش استاندارد نوشتن متون دوطرفه رو معرفی کنم، و تأکید کنم که حتماً ازش استفاده کنید و هیچوقت به‌جای این‌کار از هک‌های متداول (مثل برعکس نوشتن ترتیب نویسه‌ها) استفاده نکنید چون این کار خیلی غلطه.

چطور پازل 8 را به روش ‪C++‬ حل کنیم

اولین روز سال ۱۳۹۳ و اولین پست همین سال :) برای شروع سال چه چیزی بهتر از یه پازل فکری می‌تونه باشه؟ امروز جمعه‌ست و اول سال با آخر هفته شروع شده. آخرهفته‌ها فرصت مناسبی برای پروژه‌های کوچیک و جالب هست. خوب زومیت زحمت کشیده و پازل شمارهٔ ۳۱ام رو روز اول فروردین منتشر کرده. توی این پست می‌خوام توضیح بدم که چطوری این پازل رو حل کردم. در واقع تقلب کردم.

نصب آسان نرم‌افزار از طریق Qt Creator

روند کلی توسعهٔ نرم‌افزار با استفاده از ساختارهای کیوت خیلی سرراست و ساده هست. با این وجود ممکنه گاهی اوقات بعضی کارهای تکراری کسل‌کننده به‌نظر برسه. همگی می‌دونیم که کسل‌کنندگی بزرگترین دشمن گیک‌ها (و البته گیگتوپوس‌ها) هست. خوشبختانه توسعه‌دهنده‌های کیوت‌کریتور همگی گیک هستند و راه‌حل‌های مؤثری برای این کارها درنظر گرفته شده. اگر بخوایم یه کتابخانهٔ جدید رو با استفاده از کیوت بنویسیم، مسلماً بعد از یه مدتی دلمون می‌خواد که تست‌ش کنیم.

بیت‌کوین فارسی

حدود دو ماهه که دارم در مورد bitcoin تحقیق می‌کنم. به‌نظر من یکی از ایده‌هایی هست که دنیا رو متحول خواهد کرد. به هم زدن نظم اقتصادی دنیا با یک سیستم پولی کاملاً غیرمتمرکز چیزی‌یه که به زودی تبدیل به کابوس دولت‌ها خواهد شد. اما این پست در مورد خودِ بیت‌کوین و سیستم‌ش نیست. می‌خوام در مورد ترجمهٔ فارسی این پروژه بنویسم. متأسفانه این ترجمه به دست افراد ناشی و (البته با نیت خیر) انجام شده.

خلأ بین دانشگاه و صنعت

یه وضعیتی هست که بین بازار و دانشگاه به‌وجود اومده و خیلی اذیتم می‌کنه. من بهش میگم خلأ بین آکادمی و صنعت. شاید جای دیگه اسمش فرق کنه. البته مختص کشور ما هم نیست ولی طبق معمول بدترین حالتش توی کشور ما اتفاق افتاده {فرهنگ؟} این وضع باعث شده که بازاری ناهنجار و صنعتی عقب‌افتاده داشته باشیم. در مورد رشتهٔ خودم که مشکل رو با قد و قوارهٔ کاملش دارم می‌بینم.

مهاجرت به لینوکس در قوهٔ مجریه

دوشنبه ۱۸ شهریور بود که سایت شبکهٔ خبر، خبری رو منتشر کرد که بازخورد شدیدی بین کاربران لینوکس و توسعه‌دهنده‌های متن‌باز داخلی داشت. ماجرا به‌طور خلاصه از این قرار بود که دولت مصوبه‌ای رو تصویب کرده که براساس اون ارگان‌های مربوطه موظف هستند ظرف شش ماه برنامهٔ مهاجرت به لینوکس رو تحویل وزارت ارتباطات و فناوری اطلاعات بدن. خیلی از سایت‌ها و جوامع کاربری موضوع رو از دید خودشون تحلیل کردن و بلافاصله تحلیل‌های متنوعی منتشر شد.