بلاگ

چگونه انوع فایل فشرده سازی می‌شوند؟

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

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

فشرده سازی چگونه اتفاق می‌افتد؟

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

معروف ترین کتابخانه‌های فشرده سازی متون از دو الگوریتم فشرده سازی به طور همزمان استفاده می‌کنند تا بتوانند بازه‌ی زیادی از متن را پوشش داده و فشرده کنند. این دو الگوریتم LZ77 و Huffman Coding نام دارند.

کد هافمن پیچیده است و در این مطلب به جزئیات آن اشاره نخواهیم کرد. این الگوریتم با استفاده از راه‌های خاص ریاضی، کد‌های باینری کوتاه‌تری را به هرکدام از کلمات اختصاص می‌دهد. موضوعی که در نهایت منجر به کاهش حجم فایل می‌شود.

الگوریتم LZ77 بر خلاف کد هافمن ساده محسوب می‌شود و روشیست که در این مطلب بیشتر راجع به آن صحبت خواهیم کرد. این الگوریتم هدفش از بین بردن کلمات یکسان و جایگزین کردن آن‌ها با کلیدیست که به هر کلمه اختصاص می‌دهد. متن کوتاه زیر را در نظر بگیرید.

فشرده سازی

وقتی الگوریتم LZ77 این متن را مشاهده می‌کند متوجه می‌شود که واژه‌ی howtogeek سه مرتبه تکرار شده. بنابراین آن را به متن زیر تبدیل می‌کند:

فشرده سازی

سپس، وقتی که می‌خواهد متن را مجددا به نمایش برساند، همه‌ی کلید‌های (h)‌ که خودش ایجاد کرده بود را با howtogeek جایگذاری می‌کند.

اصطلاحا به این نوع فشرده‌ سازی، فشرده سازی «از دست ندادنی» یا lossless گفته می‌شود. به این معنی که داده‌ای که دریافت می‌کنید بعد از فشرده سازی عینا بازخوانی خواهد شد و هیچکدام از اطلاعات دریافت شده از بین نمی‌رود.

در واقع، LZ77 از لیستی از کلید‌ها استفاده نمی‌‌کند. بلکه بعد از مشاهده‌ی اولین تکرار یک کلمه، آن را به کلمه‌ی اصلی لینک می‌کند.

فشرده سازی

بنابراین وقتی به کلید (h) می‌رسد، به عقب بر می‌گردد و متوجه می‌شود که باید هرکدام از این کلید‌ها را با howtogeek جاگذاری کند.

حال به یک مثال واقعی تر اشاره خواهیم کرد. بیشتر فایل‌های متنی با کلید‌هایی به اندازه‌ی واژه‌های با تعداد حروف بسیار پایین فشرده سازی می‌شوند. برای مثال، واژه‌ی the حتی در کلماتی مثل there، their و then هم کلید گذاری می‌شود. با تکرار یک واژه در متن می‌توانید به نتایج عجیبی برسید. یک فایل متنی را ایجاد کردیم و کلمه‌ی howtogeek را ۱۰۰ بار در آن تکرار کردیم. فایل اصلی ۳ کیلوبایت حجم داشت. بعد از فشرده سازی اما حجم آن به ۱۵۸ بایت رسید. در واقع این فشرده سازی حجم فایل را تا ۹۵ درصد کاهش داد.

فشرده سازی

البته واضح است که در مثال قبلی کمی زیاده روی کردیم و با تکرار ۱۰۰ باره‌ی یک واژه نمی‌توانستیم انتظاری جز این مقدار از فشرده سازی را داشته باشیم. اما عموما در صورت استفاده از فرمت‌هایی مثل ZIP با ۳۰ تا ۴۰ درصد کاهش حجم مواجه خواهید شد.

الگوریتم LZ77 فقط روی فایل‌های متنی عمل نمی‌کند. هرچند به طور کلی فشرده سازی فایل‌های متنی بسیار ساده تر است چرا که تکرار بعضی از کلمات عموما در هر زبانی اتفاق می‌افتد.

فشرده سازی فایل‌های صوتی و ویدیویی چطور اتفاق می‌افتد؟

فشرده سازی

فشرده سازی فایل‌های ویدیویی و صوتی کاملا متفاوت اتفاق می‌افتد. بر خلاف متن که شما با فشرده سازی «از دست ندادنی» رو به رو بودید، در فشرده سازی فایل‌های ویدیویی و صوتی با فشرده سازی «از دست دادنی» مواجه هستید و برخی از اطلاعات هر فایل را بعد از فشرده سازی از دست خواهید داد. همچنین هرچه قدر میزان فشرده سازی شما بالاتر باشد، اطلاعات بیشتری را از دست می‌دهید.

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

عکسی که در بالا مشاهده می‌کنید تصویری از صفحه‌ی دسکتاپ است که چندین بار توسط نرم افزار فوتوشاپ باز شده و سپس با کیفیتی پایین تر اقدام به ذخیره سازی آن کردیم. در زیر نتیجه را خواهید دید:

فشرده سازی

البته چیزی که در بالا مشاهده می‌کنید با کمترین کیفیت ممکن اتفاق افتاده است. برای مقایسه می‌توانیم به یک فشرده سازی دیگر اشاره کنیم که این بار با فشرده سازی ۵۰ درصد رو به رو شده. در عکس زیر با یک فایل JPEG‌ مواجه هستیم که آنچنان تفاوتی با فایل PNG اصلی خود ندارد. البته اگر نخواهید خیلی دقیق به آن نگاه کنید.

فشرده سازی

فایل PNG‌ این عکس حدود ۲۰۰ کیلوبایت بود، اما بعد از فشرده سازی ۵۰ درصد تبدیل به فایلی با حجم ۲۸ کیلوبایت شد. بنابراین سوال اینجاست که آیا واقعا در این میان حجم قابل توجهی از هارد با صرفه جویی مواجه می‌شود یا نه؟

الگوریتم JPEG نتیجه‌ی شاهکار مهندسین است. بیشتر فرمت‌ها لیستی از اعداد را ذخیره می‌کنند که هر عدد نشان دهنده‌ی یک پیکسل است. فرمت JPEG‌ چنین کاری نمی‌کند. در عوض با استفاده از روشی به نام تبدیلات گسسته‌ی کسینوسی اقدام به ذخیره سازی تصاویر می‌کند. این روش با مجموعه‌ای از موج‌های سینوسی مختلف مواجه است. در این روش از ۶۴ معادله‌ی مختلف استفاده می‌شود که البته بیشترشان مورد استفاده قرار نمی‌گیرند.

در واقع متغیر تعیین کیفیت فایل‌های JPEG که در فوتوشاپ مشاهده می‌کنیم، تعداد معادله‌های مورد استفاده برای ذخیره‌سازی عکس را مشخص می‌کند. نرم افزار فوتوشاپ بعد از تعیین شدن تعداد معادلات، با استفاده از کدگذاری هافمن نسبت به فشرده سازی بیشتر عکس اقدام خواهد کرد.

این اتفاق باعث می‌شود که عکس‌های با فرمت JPEG امکان فشرده سازی بیشتری داشته باشد. البته در صورت زیاده روی ممکن است با عکسی مثل تصویر زیر مواجه شوید:

فشرده سازی

عکس بالا می‌تواند یک فاجعه لقب بگیرد. اما موضوع مهم اینجاست که عکس‌هایی با فرمت JPEG با مقدار کمی از فشرده سازی، می‌توانند با کاهش حجم قابل توجهی مواجه شوند و علاوه بر این کیفیتشان آنچنان پایین نیاید. به همین دلیل است که اکثر وبسایت‌ها از تصویر‌هایی با فرمت JPEG استفاده می‌کنند.

فشرده سازی فایل‌های ویدیویی

فشرده سازی

فشرده سازی فایل‌های ویدیویی تا حدی با فشرده سازی تصاویر متفاوت است. شاید فکر کنید هر فریم از ویدیو را با فرمت JPEG فشرده سازی می‌کنند، که یقینا این اتفاق می‌افتد؛ اما روش بهتری برای فشرده سازی فایل‌های ویدیویی وجود دارد.

ما از اصطلاحی به نام Interframe Compression به معنی «فشرده سازی میان فریمی» استفاده می‌کنیم که به محاسبه‌ی تغییرات هر بین هر دو فریم می‌پردازد و فقط آن‌ها را ذخیره می‌کند. بنابراین به عنوان مثال اگر فیلمی دارید که صحنه‌های آن زیاد تغییر نمی‌کند می‌توانید با استفاده از این روش با حجم بسیار کمتری از فایل ویدیویی مواجه شوید.

فشرده سازی میان فریمی در واقع اصلی ترین دلیلیست که ما امروزه تلویزیون‌های دیجیتال و ویدیو‌های تحت وب را داریم. بدون این فشرده سازی، ویدیو‌ها چند صد گیگابایت حجم داشتند که مقدار بسیار زیادیست. البته به یاد داشته باشید که GIF از چنین روشی استفاده نمی‌کند و به همین دلیل است که با اینکه کوتاه هستند اما حجم نسبتا زیادی دارند.

موضوع دیگری که باید در زمینه‌ی ویدیو به یاد داشته باشید موضوعیست با نام bitrate. بیت ریت به معنای مقدار داده‌‌هاییست که در هر ثانیه اجازه‌ی اجرا شدن را دارند. به عنوان مثال اگر بیت ریت ۲۰۰ کیلوبایت بر ثانیه باشد، ویدیوی شما کیفیت پایینی خواهد داشت. کیفیت فایل‌های ویدیویی در صورتی که بیت ریت بالاتر باشد، بیشتر خواهد شد.

تصویر زیر، فریمی از یک ویدیوست. تصویر سمت چپ با بیت ریت ۳ مگابایت بر ثانیه و تصویر سمت راست ۱۰۰ مگابایت بر ثانیه است.  

ویدیوی مربوط به تصویر سمت راست ۳۰ برابر حجم بیشتری نسبت به ویدیوی تصویر سمت چپ داشت. اما عملا تفاوت کیفیت قابل توجهی را شاهد نبودیم. عموما ویدیو‌های یوتوب با توجه به کیفیت اینترنتتان از بیت ریتی بین ۲ تا ۱۰ مگابایت بر ثانیه استفاده می‌کنند و در صورت استفاده از بیت ریت بالاتر، بعید است که کیفیت بهتری را در آن‌ها شاهد باشیم.

فشرده سازی فایل‌های صوتی

فشرده سازی

فشرده سازی فایل‌های صوتی شباهت زیادی به فشرده سازی متن و تصاویر دارد. فایل‌های JPEG جزئیات غیر قابل مشاهده را از تصویر حذف می‌کنند. اتفاقی که در فشرده سازی فایل‌های صوتی هم می‌افتد.

فرمت MP3 هم دارای بیت ریت است. در کیفیت‌های پایین این مقدار بین ۴۸ و ۹۶ کیلو بیت بر ثانیه، در کیفیت‌های متوسط از ۱۲۸ تا ۲۴۰ کیلوبیت بر ثانیه و در کیفیت‌های عالی از ۳۲۰ کیلوبیت بر ثانیه استفاده می‌شود. البته شنیدن تفاوت‌ها بین این فایل‌ها تنها با یک هدفون قوی و گوش تیز امکان پذیر است.

در فشرده سازی فایل‌های ویدیویی هم بعضی متد‌های فشرده سازی از دست دادنی وجود دارد. یکی از معروف ترین آن‌ها FLAC است که از الگوریتم LZ77‌ استفاده می‌کند.

نوشته چگونه انوع فایل فشرده سازی می‌شوند؟ اولین بار در دیجیاتو پدیدار شد.

گردآوری توسط ایده طلایی

ساخت کوتاه کننده لینک با لاراول

به سرم زده یه سایت ساده کوتاه کننده لینک با لاراول بسازم و نشونتون بدم چجوری میشه انجامش داد و اول کار بگم آموزش نیست و احتیاجه از قبل با لاراول آشنا باشین .به نظرم کوتاه کننده لینک ساده ترین وبسایتیه که میشه نوشت،یه جورایی HelloWorldحساب میاد!
میخوام فقط یه صفحه بسازم لینک بهش میدی و کوتاه شدش رو تحویلت میده و وقتی لینک کوتاه شده باز میشه میره توهمون صفحه ای که باید بره .
لاراول رو نصب میکنم و فایل .env روبرای دسترسی به دیتابیس اصلاح میکنم ومدل ومیگریشن وکنترلررو با آرتیسن میسازم.
php artisan make:model Link -m -c
پوشه Auth توی کنترلرها و مدلUser ودوتامیگریشن مربوط به کاربرها و ریست پسورد رو هم پاک میکنم چون بهشون احتیاجی ندارم.میگریشن لینکها رو این شکلی مینویسم.

Schema::create('links', function (Blueprint $table) {
 $table->bigIncrements('id');
 $table->string("slug")->index()->nullable(); // لینک کوتاه شده
 $table->text("url");// لینک اصلی
 });

و میگریت رو انجام میدم.

php artisan migrate

خب حالا وقتشه مدل رو آماده کنم.

class Link extends Model
{
 public $timestamps = false;
 protected $fillable = [
 'slug',
 'url'
 ];
}

خب توی کنترلم اول یه متد مینویسم که صفحه اصلی رو که شامل فرم کوتاه کننده لینک هستش نشونمون بده.

public function show(Request $request)
 {
 return view('home');
 }

یه View جدید هم حاضر میکنم اسمش رو میذارم home.blade.php .
بعد توی web.php روت اصلی رو اصلاح میکنم.

Route::get('/', 'LinkController@show');

حالا میرم سراغ آماده کردن home.blade.php و فرم رو حاضر میکنم.





 
 
 
 کوتاه کننده لینک

 
 



 

کوتاه کننده لینک


و خب حالا باید یه چیزی بنویسم که بتونم با
ajax jquery
بهش وصل شم و درخواست لینک کوتاه شده بدم.
قبل از هر چیزی من باید به یه روشی مقدار
slug
رو پر کنم که هم خیلی کوتاه باشه و هم منحصر به فرد که بعدا کاربری لینک کوتاه شده رو باز کرد اشتباهی جایی نره. پس اول یه تابع مینویسم که آی دی مدل لینک رو بگیره و بر اساس اون یه رشته خیلی کوتاه و منحصر به فرد تحویلم بده.

protected function generateSlug($id)
 {
 $id-=1; // چون آی دی ها از یک شروع میشن و رشته ها از صفر یه دونه ازش کم میکنم
 $alpha = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ123456789-_";
 $alphaLen = strlen($alpha);
 $out = "";
 while($id > 0) { // تبدیل مبنا از عدد به مبنای من در آوردی
 $out.= $alpha[$id%$alphaLen]; // یه دونه از کاراکتر ها رو میگیرم
 $id = intval($id/$alphaLen); // آی دی رو تقسیم میکنم برای گرفتن المنت بعدی
 }
 return $out;
 }

معیارم بر اساس alpha خواهد بود. اگه بعدا هر گونه دستکاری توی alpha انجام بدم همه چی به طور کل خراب میشه . به نظرم همینی که هست خوبه!
خب حالا وقت به کار انداختن تابع تولید لینک کوتاه هستش.

public function requestLink(Request $request)
 {
 // اول ولیدیشن رو انجام میدم
 $this->validate($request, [ 
 'url' => 'required|url'
 ]);
 // اگه لینک از قبل وجود داشت میگیرم یا یه دونه جدیدش رو میسازم
 $link = Link::where('url', $request->input('url'))->firstOrCreate([
 'url' => $request->input('url')
 ]);
 // مقدار اسلاگ رو بر اساس آیدی تنظیم میکنم مهم نیست از قبل ساخته شده بوده یا نه چون نتیجه بر اساس آی دی هست همیشه همون مقداره
 $link->slug = $this->generateSlug($link->id);
 // سیو میکنم
 $link->save();
 return [ 
 'slug' => $link->slug
 ];
 }

و در نهایت به روت هام اضافه ش میکنم.

Route::post('/request-link', 'LinkController@requestLink')->name("request_link");

حالا وقت نوشتن کد های jquery هست برای کوتاه کردن لینک.

خب اینم از این فقط یه چیز دیگه باقی میمونه اونم اینه که به جای این چیز بیخودی یه لینک به جاش به کاربر بدیم که بتونه ازش استفاده کنه.
اول متد ریدایرکت کردن رو مینویسم.

public function openLink($slug)
 {
 return redirect()->to(Link::where('slug', $slug)->firstOrFail()->url);
 }

و به روت ها اضافه ش میکنم.

Route::get('/o/{slug}', 'LinkController@openLink')->name("open_link");

و در نهایت

requestLink

رو یه کم اصلاحش میکنم.

return [ 
 'slug' => route("open_link", ['slug' => $link->slug])
 ];

خب اینم از سایت ساده کوتاه کننده لینک و خب چون که توی ویرگول نمیشه کدها رو به خوبی مشاهده کرد من یه نسخه از این رو روی گیت هاب آپلود میکنم که بتونین اونجا مشاهده کنین

https://github.com/amir9480/laravel-url-shortener-sample

نوشته ساخت کوتاه کننده لینک با لاراول اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

انتخاب روز تولد مریم میرزاخانی به عنوان «روز جهانی زن در ریاضیات»

بیش از یک سال از مرگ نابغه ریاضی جهان می‌گذرد و حالا خبر می‌رسد که اتحادیه بین‌المللی انجمن‌های ریاضی جهان با پیشنهاد کمیته بانوان انجمن ریاضی ایران، روز تولد مرحومه «مریم میرزاخانی»، سوم ماه می (۱۳ اردیبهشت) را روز جهانی زن در ریاضیات نامگذاری کرد.

این خبر را دکتر «مژگان محمودی»، دبیر کمیته بانوان انجمن ریاضی ایران به سایت اینسا داده و اعلام کرده که این پیشنهاد در ۹ مردادماه  در جلسه عمومی بانوان اتحادیه بین‌المللی انجمن‌های ریاضی جهان تصویب شده و امروز رسما اطلاع رسانی می‌شود:

«متن این پیشنهاد را اعضای کمیته بانوان به کمک دکتر رحیم زارع نهندی و دکتر سیاوش شهشهانی تهیه کردند و دکتر دانش‌خواه نیز آن را در دومین کنفرانس بانوان ریاضیدان جهان در برزیل ارائه کرد.»

روز جهانی زن در ریاضیات

مریم میرزاخانی، ریاضی‌دان ایرانی و استاد دانشگاه استنفورد در ۱۳ اردیبهشت سال ۱۳۵۶ در تهران متولد شد و در سال ۱۹۹۴ میلادی، میرزاخانی ۱۷ ساله به همراه دوست چندین ساله اش تیم المپیاد ریاضی ایران را تشکیل دادند و میرزاخانی با نمره ای که به دست آورد توانست مدال طلا را کسب کند.

سال ۱۹۹۹ میلادی بعد از آنکه مریم درسش را در مقطع کارشناسی رشته ریاضیات دانشگاه شریف به پایان رساند برای ادامه تحصیل به هاروارد رفت و در  تز دکترای خود که در سال ۲۰۰۴ میلادی آن را دریافت کرد به موضوع هندسه هذلولوی پرداخت. چند سال بعد در دانشگاه استنفورد مشغول به کار شد.

روز جهانی زن در ریاضیات

آنچه بیش از همه باعث شهرت خانم میرزانی خانی شد موفقیت وی در کسب مدال فیلدز است. در ۱۳ آگست سال ۲۰۱۴ میلادی، پارک گون هه رئیس جمهور وقت کره جنوبی درجریان کنگره بین المللی ریاضیات که در سئول برگزار گردید، مدال فیلدز را به خانم میرزاخانی و سه تن دیگر از برندگان اعطا کرد.

این نابغه ریاضی ایرانی پس از چهار سال مبارزه با بیماری سرطان سینه خود سرانجام در بیست‌وسوم تیر ماه ۱۳۹۶ دار فانی را وداع گفت.

نوشته انتخاب روز تولد مریم میرزاخانی به عنوان «روز جهانی زن در ریاضیات» اولین بار در دیجیاتو پدیدار شد.

گردآوری توسط ایده طلایی

مثال های کاربردی ریدایرکت در htaccess

در مقاله قبلی  توضیحات کاملی در مورد فایل htaccess و کاربرد های آن  و اینکه این فایل چگونه ایجاد می شود، تشریح شد. یکی از پرکاربردترین استفاده ای که از فایل htaccess انجام می شود، ریدایرکت یا فوروارد می باشد، در این مقاله برخی از پرکاربردترین کدهای ریدایرکت را معرفی می کنیم.

 

ریدایرکت  http به https

RewriteEngine On

RewriteCond %{HTTPS} off

RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

 

ریدایرکت https با (www   (https://www به بدون  www

RewriteEngine On

RewriteCond %{HTTPS} off [OR]

RewriteCond %{HTTP_HOST} ^www. [NC]

RewriteRule ^ https://okex.ir%{REQUEST_URI} [L,NE,R=301]

 

ریدایرکت آدرس سایت بدون www به آدرس با www

RewriteEngine on

RewriteCond %{HTTP_HOST} ^example.com [NC]

RewriteRule ^(.*)$ http://www.example.com/$1 [L,R=301,NC]

بجای عبارت example.com که نام دامنه میباشد باید ادرس دامنه خودتان را وارد کنید.

 

ریدایرکت آدرس سایت با www به آدرس بدون www

RewriteEngine on

RewriteCond %{HTTP_HOST} ^www.example.com [NC]

RewriteRule ^(.*)$ http://example.com/$1 [L,R=301,NC]

بجای عبارت example.com که نام دامنه میباشد باید ادرس دامنه خودتان را وارد کنید.

 

ریدایرکت http به  https  بجز یک دایرکتوری یا  فولدر



RewriteCond %{HTTPS} on

RewriteRule ^%{HTTP_HOST}/demo(.*) http://%{HTTP_HOST}/demo/$1 [R=301,L]

RewriteRule ^index.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /index.php [L]

در مثال بالا نام دایرکتوری مورد نظر را جایگزین  demo کنید.

ریدایرکت فقط یک پوشه از سایت بر بستر https

RewriteEngine On

RewriteCond %{SERVER_PORT} 80

RewriteCond %{REQUEST_URI} folder

RewriteRule ^(.*)$ https://www.example.com/folder/$1 [R,L]

در این مثال بایستی folder را با نام پوشه مورد نظر جایگزین نموده و بجای www.example.com نام دامنه مورد نظر را درج کنید.

 

ریدایرکت ساب دامنه بر روی دامنه اصلی

#Options +FollowSymlinks

RewriteEngine On

RewriteCond %{HTTP_HOST} ^sub.domain.com$ [OR]

RewriteCond %{HTTP_HOST} ^www.sub.domain.com$

RewriteRule (.*)$ http://domain.com/$۱ [R=301,L]

 

ریدایرکت یک فایل در   htaccess

RedirectMatch 301 /oldurl  /newurl

 

ریدایرکت تمامی آدرس های یک دامنه به یک آدرس خاص

RedirectMatch 301 / /newurl

ریدایرکت از نوع موقت (۳۰۲)

Redirect 302 / http://domain.com/

 

ریدایرکت دامنه قدیمی به دامنه جدید

RewriteEngine on

RewriteCond %{HTTP_HOST} ^ domain.ir [NC,OR]

RewriteCond %{HTTP_HOST} ^www.domain.ir [NC]

RewriteRule ^(.*)$ http://domain.com/$1 [L,R=301,NC]

نام دامنه قدیمی را جایگزین domain.ir و نام دامنه جدید را جایگزین  domain.com کنید.

 

ریدایرکت یک صفحه به صفحه دیگر

Redirect /old-index.html http://www.mynewwebsite.com/foldername/new-index.html

 

ریدایرکت دامنه پارک شده به ساب دامنه

RewriteEngine on

RewriteBase /

RewriteCond %{HTTP_HOST} ^(www.)?parkdomain.com$ [NC]

RewriteRule ^(.*)$ http://maindomain/subdomain [L]

نام دامنه پارک شده را جایگزی parkdomain.com و بجای maindomain/subdomain  آدرس ساب دامنه مورد نظر را درج کنید.

 

ریدایرکت دامنه اصلی به ساب دامنه

Options +SymLinksIfOwnerMatch

RewriteEngine on

RewriteCond %{HTTP_HOST} ^(www.)?domain.com$ [NC]

RewriteRule ^http://sub.domain.com[R,L]

بجای domain و .com نام دامنه و پسوند آن را درج نموده و بجای  sub.domain.com نام ساب دامنه مورد نظر را درج کنید.

 

ریدایرکت webmail

با کد زیر می توانید webmail.domian.com را به domain.com/webmail ریدایرکت کنید.

RewriteEngine on

RewriteBase /

RewriteCond %{HTTP_HOST} ^(www.)?webmail.domain.com/$ [NC]

RewriteRule ^(.*)$ http:// domain.com/webmail/ [L]

نام دامنه مورد نظر را جایگزین domain.com نمائید.

 

ریدایرکت ساب دامنه به ip با پورت

RewriteEngine on

RewriteCond %{HTTP_HOST} ^subsonic.mydomain.com$ [NC]

RewriteRule ^(.*)$ http://ip:4040/$1 [R=301]

 

ریدایرکت کردن کل ترافیک سرور بر روی https

RewriteEngine On

RewriteCond %{SERVER_PORT} 80

RewriteRule ^(.*)$ https://www.example.com/$1 [R,L]

با قرار دادن این کد ها کل ترافیک هاست به https://www.example.com ریدایرکت می شود.

 

ریدایرکت یک پسوند خاص صفحات سایت به پسوند دیگر

 RedirectMatch 301 (.*).html$ http://domain.com$1.php

با این کد، صفحاتی نظیر http://domain.com/Page.html به http://domain.com/Page.php ریدایرکت ۳۰۱ می شود.

 

 

نوشته مثال های کاربردی ریدایرکت در htaccess اولین بار در ایران سرور پدیدار شد.

گردآوری توسط ایده طلایی

htaccess چیست و چه کاربردی دارد؟

 htaccess چیست؟

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

با استفاده از این فایل شما می توانید صفحه ای را به صفحه دیگر ریدایرکت کنید ، پسوند فایل را تغییر دهید ، روی پوشه رمز گذاری نمائید و مواردی از این قبیل را بسادگی انجام دهید.

فایل htaccess کجاست ؟ نحوه دسترسی به htaccess  چگونه است؟

این فایل بصورت معمول در  دایرکتوری public_html هاست وجود دارد. در اغلب  سیستم های مدیریت محتوا مثل وردپرس و دروپال این فایل بصورت خودکار ایجاد می شود.

در صورتیکه کنترل پنل  هاست شما  cpanel می باشد، این کنترل پنل بصورت پیش فرض فایل های مخفی را نمایش نمی دهد، بنابراین جهت نمایش فایل های مخفی بصورت زیر اقدام نمائید:

در پوشه Fle Manager در گوشه بالا سمت راست صفحه بر روی دکمه Settings کلیک کنید تا پنجره پاپ آپ مربوط به تنظیمات فایل منیجر نمایش داده شود.

در پنجره پاپ آپ باز شده تیک گزینه Show Hidden Files را بزنید و روی save کلیک کنید.

با این تغییر پس از ذخیره می‌توانید وارد پوشه  public_html شوید و فایل htaccess را مشاهده نمایید . در پوشه Home نیز سایر پوشه های مخفی نظیر Trash که فایل های حذف شده در آن قرار دارد قابل مشاهده خواهد بود .

 

معرفی سایت جهت ساخت htaccess

شما از طریق سایت htaccesseditor.com بسادگی می توانید با توجه به کاربرد مورد نظرتان کدی که لازم است در htaccess درج کنید را تولید نموده و در فایل htaccess سایت خود اضافه کنید.

 

کاربرد های htaccess

این فایل که معمولا با نصب CMSهای معروف و Open Source مانند WordPress، Joomla و Drupal به صورت خودکار در مسیر اصلی اسکریپت ایجاد و محتوا سازی می شود، عهده‌دار وظایف مهمی نظیر موارد زیر می‌باشد:

 

تغییر عنوان و فرمت فایل اصلی index

شما با استفاده از این کد می توانید نام و فرمت فایل اصلی سایت خود را تغییر دهید

DirectoryIndex file.php file.htm

 

جلوگیری از سرقت فایلهای و فولدرهای درون هاست

بیشتر وقتها اطلاعاتی مثل فایل‌های قالب اختصاصی شما که بر روی هاست قرار دارند و یا فایل‌هایی که به صورت zip شده در هاست خود ذخیره کرده‌اید به راحتی با مرور هاست شما توسط سایرین کشف و به سرقت میرود، برای جلوگیری از این امر کد زیر رو در اننهای فایل htaccess قرار دهید.

Options All -Indexes

 

محدودیت دسترسی با ip های خاص در  htaccess

در برخی مواقع مثل بازدیدهای غیر واقعی که درخواست های زیادی از یک یا رنجی از ip به سایت شما  ارسال می شوند و باعث کاهش سرعت لود سایت شما می گردند و یا مسدود کردن ip اسپمرها می توانید Ip های مورد نظر را از طریق فایل  htaccess محدود کنید.

deny from 1.2.3.4

allow from all

بجای ۱٫۲٫۳٫۴  نیاز است  ip  یا رنج ip مورد نظر را اضاف کنید.

همچنین برای امنیت مدیریت سایت شما نیز می توانید در مسیر  مدیریت سایت بعنوان مثال در وردپرس در مسیر wp-admin  یک فایل .htaccess ایجاد نموده و دسترسی کلیه Ip ها بغیر از ip استاتیک خودتان را محدود کنید بدین شکل تنها از سیستم شما به مسیر مدیریت سایت دسترسی وجود خواهد داشت.

deny from all

allow from 1.2.3.4

بجای ۱٫۲٫۳٫۴  نیاز است  ip  یا رنج ip مورد نظر را اضاف کنید.

 

افزایش امنیت فایل در htaccess (ایجاد محدودیت در دسترسی به فایل)

جهت عدم دسترسی سایرین به برخی از فایل های مهم سایت مثل فایل های کانفیگ کد زیر را در htaccess درج کنید:



order allow,deny

deny from all

بجای wp-config.php نیاز است نام فایل مورد نظر را درج نمائید.

 

مخفی کردن لیست دایرکتوری ها

یکی از مشکلاتی که در سایت ها وجود دارد قابلیت مشاهده کردن فایل ها و پوشه ها میباشد که موجب میشود تا هر کسی بتواند محتوای آپلود شده در سایت شما را ببیند و  بعنوان مثال قادر خواهند بود قالب سایت شما را کپی کنند.

جهت جلوگیری از این مشکل کد زیر را در htaccess درج کنید:

Options –Indexes

 

کش شدن سایت بر روی مرورگر با کد  htaccess

کش شدن سایت بر روی مرورگر باعث میشود مصرف ترافیک ، مصرف رم و cpu در سایت شما کاهش یابد و در نتیجه سرعت لود شدن سایت شما افزایش یابد.

کد زیر را در انتهای فایل htaccess قرار دهید:

# Enables browser caching



ExpiresActive On

ExpiresByType image/jpg "access 1 year"

ExpiresByType image/jpeg "access 1 year"

ExpiresByType image/gif "access 1 year"

ExpiresByType image/png "access 1 year"

ExpiresByType text/css "access 1 month"

ExpiresByType application/pdf "access 1 month"

ExpiresByType text/x-javascript "access 1 month"

ExpiresByType application/x-shockwave-flash "access 1 month"

ExpiresByType image/x-icon "access 1 year"

ExpiresDefault "access 2 days"

 

محدود کردن نوع فایلهای قابل اجرا و نمایش

برای حفظ امنیت و اطلاعات سایت می‌توانید پسوند فایل‌هایی که بتوان اجرا کرد رو تعیین کنید :

Options +FollowSymlinks

RewriteEngine On

rewritecond %{REQUEST_FILENAME} !^(.+).css$

rewritecond %{REQUEST_FILENAME} !^(.+).js$

rewritecond %{REQUEST_FILENAME} !file.php$

RewriteRule ^(.+)$ /deny/ [nc]

 

اضافه کردن mime-type از طریق htaccess

حذف پرسش سرور پیرامون اینکه فایل را باز می نمایید و یا دانلود می کنید. براحتی فایل مورد نظر را download  نمایید.

AddType application/octet-stream .pdf

AddType application/octet-stream .zip

AddType application/octet-stream .mov

 

فعال کردن  gzip

شما از طریق htaccess می توانید gzip-compression  را فعال نموده و این تغییر در افزایش سرعت سایت موثر می باشد، جهت کسب اطلاعات بیشتر در این زمینه مقاله gzip-compression را مطالعه نمائید، در این مقاله کدهای مختلف فعالسازی برای سیستم های مدیریت محتوا و وب سرور های گوناگون ذکر شده است.

 

ایجاد محدودیت در آپلود فایل

از طریق کد زیر می توانید حداکثر حجم فایل قابل آپلود رو ۲۰ مگابایت تنظیم کنید.

php_value upload_max_filesize 20M

 

ایجاد محدودیت در حجم پست ارسالی

از طریق کد زیر می توانید حداکثر حجم هر پست رو ۲ مگابایت مشخص کنید.

php_value post_max_size 2M

 

تنظیم محدودیت حافظه memory_limit

از طریق کد زیر می توانید میزان محدودیت حافظه را مشخص کنید.

php_value memory_limit 128M

 

تعریف ریدایرکت در htaccess

یکی از پر کاربردترین موارد در htaccess امکان تعریف ریدایرکت و فوروارد است. شما می توانید از طریق درج کد در این فایل سایت یا لینک های مختلف آن را به آدرس دیگری هدایت کنید، یا مشخص کنید سایت با http  به  https و یا با www به بدون www ریدایرکت شود.

در مقاله مثال های کاربردی ریدایرکت در htaccess می توانید برخی از پر کاربردترین کد های ریدایرکت را مشاهده کنید.

ریدایرکت از طریق Htaccess

بعنوان مثال از طریق کد زیر می توانید http را به https ریدایرکت کنید:

RewriteEngine On

RewriteCond %{HTTPS} off

RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]

 

تغییر صفحه پیش فرض

با استفاده از کد زیر می توانید مشخص کنید، صفحه پیش فرض سایت چه صفحه ای باشد یعنی در زمان لود سایت ابتدا چه صفحه ای بارگذاری شود و یا اولویت نمایش صفحات پیش فرض را مشخض کنید.

#Alternate default index pages

DirectoryIndex first.html index.htm index.html index.php

 

ایجاد صفحات پیش فرض خطا

ایجاد صفحه خطای اختصاصی به این معناست که مثلا لحظه‌ای وبسایت شما با یکی از خطاهای رایج HTTP که در بالا در مورد برخی از آن‌ها صحبت شد، مواجه می‌شود؛ برای مثال فایل یا صفحه‌ای وجود ندارد و بازدید کننده با وارد کردن آدرسی که در سرور و وبسایت شما وجود ندارد با خطای ۴۰۴ مواجه می‌شود. حال ممکن است او معنی این خطا را نداند و یا حتی اگر بداند باز دچار سردرگمی شود و از بازدید وبسایت شما منصرف شود. در این شرایط چنانچه ما از پیش صفحه‌ای ساخته باشیم تا بازدیدکننده به جای مواجهه با خطای ۴۰۴، وارد صفحه‌ای شود که به درستی به او این پیغام را دهد که «فایل مورد نظر وجود ندارد؛ ممکن است این فایل به دلیلی حذف و یا جابه‌جایی آن به مسیر دیگر روی داده باشد»، این گونه بازدیدکننده حس بهتری نسبت به آن خطا پیدا می‌کند.

ErrorDocument 401 /error_pages/401.html
ErrorDocument 404 /error_pages/404.html
ErrorDocument 500 /error_pages/500.html

 

نحوه جلوگیری از عمل Hotlink در فایل  .htaccess (جلوگیری از استفاده تصاویر سایت در سایت های دیگر)

Hotlink Protection  باعث می‌گردد از کپی شدن اطلاعات شما در وبسایت‌های دیگر جلوگیری شود برای مثال چنانچه تصویری در یک دایرکتوری از سرویس میزبانی شما وجود دارد، از نمایش آن تصویر در وبسایت‌های دیگر جلوگیری به عمل می‌آید و همچنین چنانچه فایلی قابلیت دانلود با لینک مستقیم با استفاده از وبسایت شما را دارد و لینک مذکور در وبسایتی دیگر کپی گردیده باشد، کاربران آن وبسایت با کلیک بر روی لینک مذکور ابتدا به آدرس وبسایت شما ارجاع داده می‌شوند.  این امر باعث افزایش ترافیک و لود سایت شما می شود. در این صورت پهنای باند شما در حالی به پایان می رسد که بازدیدها از سایت شما صورت نگرفته است.

با استفاده از htaccess مانع از استفاده ی مطالب خود در سایر وب سایت ها می شوید مخصوصا استفاده از تصاویر وب سایت شما.

توجه داشته باشید ، این قابلیت مستلزم آن است که از mod_rewrite است بر روی سرور شما فعال باشد.بنابراین حتما با مدیر سیستم خود و یا شرکت میزبانی وب ارتباط برقرار نمایید.

دستورالعمل جلوگیری از استفاده از مطالب برای فایل ها با فرمت های ‘GIF’ ، ‘ JPG’ و ‘CSS’ که باید در فایل htaccess قرار بگیرد در زیر آمده است:

RewriteEngine on

RewriteCond %{HTTP_REFERER} !^$

RewriteCond %{HTTP_REFERER} !^http://(www.)?yourdomain.com/.*$ [NC]

RewriteRule .(gif|jpg|css)$ - [F]

‘yourdomain.com’ با آدرس وب سایت جایگزین میشود.

 

مسدود کردن حملات XSS

هدف از حمله XSS، تزریق کدهای مخرب برای اجرا در صفحات وبی که به کاربرانشان اعتماد کرده اند(اگر بخواهیم خوش بین باشیم) است. این کدها مانند کدهایی که از سمت سرور به سمت کلاینت میرسند، اجرا خواهند شد و میتوانند به همه اطلاعاتی که کاربر میتواند دسترسی داشته باشد، دسترسی پیدا کنند مانند کوکی، Session و … .

# Blocks some XSS attacks



RewriteCond %{QUERY_STRING} (|%3E) [NC,OR]

RewriteCond %{QUERY_STRING} GLOBALS(=|[|%[0-9A-Z]{0,2}) [OR]

RewriteCond %{QUERY_STRING} _REQUEST(=|[|%[0-9A-Z]{0,2})

RewriteRule .* index.php [F,L]

 

اعمال رمز عبور برای دایرکتوری‌(Password Protection)

با اعمال چند خط کد ساده در فایل htaccess. می‌توان دسترسی به دایرکتوری‌ها را با تعریف نام‌ کاربری و رمز عبور در فایلهای htpasswd. کنترل نمود.

 

محتویات htaccess پیشفرض در وردپرس

بصورت پیش فرض فایل Htaccess وردپرس شامل کد زیر می باشد،  در صورتیکه این فایل وجود نداشته باشد یا این کد از htaccess حذف شود صفحات داخلی سایت شما باز نخواهد شد و با ارور ۴۰۴ مواجه می گردد.

# BEGIN WordPress



RewriteEngine On

RewriteBase /

RewriteRule ^index.php$ - [L]

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /index.php [L]



# END WordPress

 

حفاظت از htaccess. از دسترسی غیر مجاز

همانطور که مشاهده کردید، کارهای زیادی وجود دارد که می توانید با استفاده از فایل htaccess. انجام دهید.  با توجه به قدرت و کنترل آن بر روی وب سرور شما مهم است که این فایل را از دسترسی غیرمجاز توسط هکرها محافظت کنید. جهت حفاظت از این فایل به سادگی کد زیر را در فایل htaccess. خود اضافه کنید:



order allow,deny

deny from all

 

 

 

نوشته htaccess چیست و چه کاربردی دارد؟ اولین بار در ایران سرور پدیدار شد.

گردآوری توسط ایده طلایی

آموزش زبان برنامه‌نویسی Rust – قسمت ۱: شروع کار با متغیّرها و ثوابت

در قسمت قبل نحوه‌ی نصب Rust روی سیستم‌عامل‌های مختلف‌ را دیدیم و اوّلین برنامه خودمان‌را در این زبان نوشتیم.

اگر آن قسمت‌را نخوانده‌اید همین الان به سراغش بروید. چون بدون دانستن آن چیز زیادی از این قسمت دستگیرتان نخواهد شد.

ابتدای این جلسه, همانطوری که در انتهای جلسه‌ی قبل گفتم, با هم ساختار برنامه‌ی Hello World که ساختار کلّی برنامه‌های دیگر هم به این زبان هست را بررسی می‌کنیم.

https://virgool.io/Software/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B2%D8%A8%D8%A7%D9%86-%D8%A8%D8%B1%D9%86%D8%A7%D9%85%D9%87%D9%86%D9%88%DB%8C%D8%B3%DB%8C-rust-%D9%82%D8%B3%D9%85%D8%AA-0-%D9%85%D8%B9%D8%B1%D9%81%DB%8C-%D9%88-%D8%B4%D8%B1%D9%88%D8%B9-%D8%A8%D9%87-%DA%A9%D8%A7%D8%B1-nwqjyzch0lde

ساختار برنامه‌ی Hello World

برنامه‌ای که با هم در قسمت قبل نوشتیم این بود:

حالا زمان این است که بفهمیم هر خط این برنامه چه معنایی دارد.

برنامه با این خط شروع می‌شود:

همانطور که احتمالاً خودتان هم حدس می‌زنید, fn مخفف کلمه‌ی function است. وقتی که این کلمه‌ی کلیدی به کار برده می‌شود یعنی داریم یک تابع‌را اعلان می‌کنیم.

اگر قبل از این با زبان C یا cpp کار کرده باشید حتماً به خاطر دارید که وقتی برنامه اجرا می‌شد تنها کدهای درون تابع main بودند که اجرا می‌شدند. در زبان Rust هم همین‌طور است. یعنی کدهایی که داخل تابع main قرار دارند اجرا می‌شوند و اگر کدی درون این تابع فراخوانی نشده باشد, اجرایی نخواهد شد.

هر برنامه‌ای که به زبان Rust نوشته می‌شود باید تابعی به نام main داشته باشد, در غیر این صورت هنگام کامپایل با خطای زیر روبه‌رو می‌شوید:

وقتی به این خطا برخورد می‌کنید با یکی دیگر از جذّابیّت‌های زبان Rust روبه‌رو می‌شوید. زیر متن ارور راهنمای زیر نوشته شده است:

یکی از نقاط قوّت این زبان پیغام‌های خطای دقیق و واضح آن است که عموماً با راهنمایی‌هایی برای رفع آن خطا همراه اند. این ویژگی‌را با خطاهای C مقایسه کنید که گاهی اوقات آدم‌را چندین روز سرکار می‌گذارند و اکثر اوقات مشکل واقعی را نمی‌گویند.

پرانتزهای بعد از اسم تابع محل قرارگیری پارامترهای تابع هستند. از آنجایی که تابع main پارامتر ورودی ندارد, پس درون پرانتزها چیزی نمی‌نویسیم.

مانند خیلی از زبان‌های دیگر, کدهای تابع درون { و } قرار می‌گیرند. پس حالا که به آکولاد باز رسیدیم وقت آن است که سراغ خط بعدی برویم تا ببینیم درون تابع چه اتّفاقی می‌افتد.

برای اکثر برنامه‌نویس‌ها وجود علامت ! در آخر اسم تابع خیلی عجیب است. شما هم حق دارید که با دیدن این علامت تعجّب کنید, چون !println اصلاً تابع نیست, بلکه یک macro در زبان Rust است. در مورد macro ها بعداً به صورت کامل بحث می‌کنیم. برای الان فقط کافی است بدانید که وقتی پای ! درمیان است, داریم از یک macro استفاده می‌کنیم.

ماکرو !println محتوایش‌را داخل ترمینال یا cmd به کاربر نمایش می‌دهد. ورودی این ماکرو می‌تواند string یا عدد باشد.

در آخرین خط هم با گذاشتن { تابع‌را می‌بندیم و کمپایلر می‌فهمد که کدهایی که از اینجا به بعد نوشته شده‌اند به این تابع ربطی ندارند.

حالا که با ساختار کلّی یک برنامه در زبان Rust آشنا شدیم, وقت آن است که به سراغ متغیّرها و ثابت‌ها برویم. امّا قبل از آن باید یک مفهوم کلیدی را با همدیگر مرور کنیم.

تغییرپذیر و غیرقابل تغییر

تغییرپذیر(mutable) و غیرقابل تغییر(immutable) دو مفهوم ساده اند که موقع نوشتن برنامه موجب خطاهای زیادی می‌شوند.

یک داده‌ی تغییرپذیر, داده‌ای است که پس از اینکه برای اوّلین بار مقدار دهی شد, می‌توان همچنان مقدار آن‌را عوض کرد. امّا یک داده‌ی غیرقابل تغییر پس از مقداردهی اوّلیّه دیگر قابلیّت مقداردهی ندارد.

دیدید چقدر ساده بود؟ حالا قرار است با یکی از بزرگترین تفاوت‌های زبان Rust با زبان‌های دیگر روبه‌رو شوید. نفس‌هایتان‌را حبس کنید.

متغیّر در زبان Rust

متغیّر یک بخش موقّتی از حافظه است که با یک نام خاص مشخّص می‌شود. تا اینجا همه‌ی زبان‌ها با هم مشابه اند. تفاوت Rust در اینجاست که متغیّرها در این زبان به صورت پیش‌فرض غیرقابل تغییر(immutable) هستند. یعنی به صورت پیش‌فرض, پس از مقداردهی اوّلیّه نمی‌توان مقدار آن‌ها را تغییر داد.

نحوه‌ی تعریف یک متغیّر

احتمالاً خیلی تعجّب کرده اید. برای اینکه گیج نشوید قبل از ادامه دادن به سراغ syntax متغیّر در زبان Rust می‌رویم:

خودم هم می‌دانم که این جور نوشتن گیج‌کننده است, ولی اگر اضافه‌اش نمی‌کردم متن ناقص می‌ماند.

خب برویم سراغ توضیح دادن این syntax. برای تعریف یک متغیّر ابتدا باید کلمه‌ی کلیدی let نوشته شود. با نوشتن این کلمه همه می‌فهمند که قرار است به زودی متغیّری در این مکان زاده شود.

بعد از کلمه‌ی let باید اسم متغیّر نوشته شود. اسم متغیّر نمی‌تواند با عدد شروع شود و تنها می‌تواند شامل اعداد و حروف باشد. در زبان Rust هرجا که در مورد حروف حرف می‌زنیم, منظور تمامی کاراکترهایی است که توسّط UTF-8 پشتیبانی می‌شوند. امّا هنگام اسم‌گذاری متغیّرها و توابع باید دقّت‌کنید. هنوز پشتیبانی از کاراکترهای غیر ASCII خوب نیست و نوشتن اسامی متغیّرها با کاراکترهای غیر اسکی ممکن است دردسرساز شود.

در اکثر موارد خود کامپایلر type متغیّر را تشخیص می‌دهد و لازم نیست که ما هم نوع‌را بنویسیم. ولی برای مواردی که ممکن است تعریف type لازم باشد, باید بعد از اسم متغیّر علامت : گذاشت و type را نوشت. در مورد type های مختلف در جلسات بعدی صحبت می‌کنیم.

شما می‌توانید یک متغیّر را اعلان کنید ولی همانجا مقداردهیش نکنید. یا می‌توانید همانجا این کار را بکنید.

حالا در کد زیر ۳ متغیّر مختلف‌را می‌نویسم تا حالت‌های مختلف‌را با هم ببینیم و دیگر چیز گنگی باقی نماند:

گفتیم که متغیّرهای Rust غیرقابل تغییر هستند. پس ما نمی‌توانیم پس از اوّلین مقداردهی دیگر مقدار آن‌ها را تغییر دهیم.

مثلاً برنامه‌ی زیر را ببینید:

فکر می‌کنید با کامپایل این کد چه اتّفاقی می‌افتد؟ همانطور که احتمالاً خودتان هم حدس می‌زنید, ارور می‌گیریم:

همانطور که در متن خطا می‌بینید, ما اجازه‌ی اینکه دوباره به یک متغیّر immutable مقدار بدهیم را نداریم.

چگونه متغیّرهای تغییرپذیر داشته باشیم؟

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

راه حل ساده است. باید هنگام تعریف متغیّر بگوییم که می‌خواهیم این متغیّر mutable باشد. برای این کار کافی است که کلمه‌ی کلیدی mut را قبل از اسم متغیّر اضافه کنیم.

مثلاً همین برنامه‌ای که چند خط بالاتر نوشتیم را درنظر بگیرید. می‌خواهیم متغیّر x را قابل تغییر کنیم. برنامه این شکلی خواهد شد:

حالا اگر این برنامه‌را اجرا کنید دیگر هیچ اروری دریافت نخواهید کرد.

ثابت‌ها در زبان Rust

ثابت(constant)ها, همانطوری که از اسمشان پیداست قابل تغییر نیستند. در زبان Rust برای تعریف یک ثابت, باید از syntax زیر پیروی کنیم:

تعریف یک ثابت با کلمه‌ی کلیدی const آغاز می‌شود. بعد از این کلمه, اسم ثابت آورده می‌شود. بعد از اسم علامت : قرار می‌گیرد و بعد از آن نوع ثابت ذکر می‌شود. بعد از آن هم با گذاشتن علامت = مقدار آن ثابت را می‌نویسیم.

برخلاف متغیّرها شما باید type ثابت را همیشه ذکر کنید. برای مثال خط زیر یک ثابت عددی در زبان Rust است(در مورد i32 در جلسات بعد توضیح می‌دهم. همین که بدانید یک نوع داده ی عددی است کافی است):

تفاوت متغیّر با ثابت

دیدیم که متغیّرها به صورت پیش‌فرض غیرقابل تغییر هستند. پس شاید الان برایتان این سؤال پیش آمده باشد که اصلاً دیگر چه نیازی به ثوابت داریم؟

حالا با هم تفاوت‌های اصلی متغیّر و ثابت را می‌بینیم:

۱-شما نمی‌توانید یک ثابت را mutable کنید. همچنین باید همیشه نوع آن را ذکر کنید. وگرنه با ارور مواجه می‌شوید.

۲- برخلاف متغیّرها, ثوابت‌را می‌توان در تمام scope ها تعریف کرد. یعنی می‌توان یک ثابت‌را به صورت عمومی(global) تعریف کرد.

کد زیر را ببینید:

اگر برنامه‌ی بالا را کامپایل کنید با خطای زیر مواجه می‌شوید:

یعنی متغیّرها حتماً باید درون یک scope محلّی(مثل بدنه‌ی یک تابع) باشند.

۳- شما نمی‌توانید یک ثابت‌را با خروجی یک تابع مقدار دهی کنید. امّا حتّی یک متغیّر غیرقابل تغییر را هم می‌توان برای اوّلین بار با خروجی یک تابع مقدار دهی کرد.

مثلاً کد زیر را درنظر بگیرید(فعلاً به syntax تابع function توجّه نکنید. این مورد را هم قول می‌دهم که بعداً توضیح بدهم):

وقتی که این برنامه‌را کامپایل کنید با ارور زیر مواجه می‌شوید:

امّا شما به راحتی می‌توانید مقدار یک متغیّر mutable یا immutable را برابر با خروجی یک تابع بگذارید.

این بار به این کد توجّه کنید:

اگر این برنامه‌را کامپایل کنید هیچ اروری نخواهید گرفت.

۴- مورد استفاده‌ی متغیّر و ثابت با هم متفاوت است. ثابت‌ها عموماً برای کنترل بخش‌های مختلف برنامه استفاده می‌شوند و هدف استفاده از آن‌ها جلوگیری از hardcode کردن چنین بخش‌هایی است. امّا متغیّرها مستقیماً برای نگهداری داده‌های کاربردی و منطق برنامه استفاده می‌شوند.

هدف از immutable کردن متغیّرها در Rust چیست؟

حالا بیایید کمی به فلسفه‌ی پشت این تصمیم سازندگان این زبان بپردازیم. چرا باید متغیّرهارا غیرقابل تغییر کنیم؟

مسئله به یک مشکل قدیمی و همیشگی برمی‌گردد. وقتی داریم یک برنامه‌ی هم‌روند(concurrent) می‌نویسم, خیلی وقت‌ها حالتی به نام race condition پیش می‌آید.

در این حالت ۲ یا چند بخش از برنامه که دارند به صورت همزمان اجرا می‌شوند, به صورت همزمان به یک بخش از داده‌ها دسترسی پیدا می‌کنند و آن‌را تغییر می‌دهند. یعنی وسط کار یک thread, ناگهان thread بعدی به داده‌های مشترک دسترسی پیدا می‌کند و آن‌را تغییر می‌دهد. وقتی که thread اوّل می‌خواهد به کارش ادامه بدهد با داده‌ای که خراب شده است روبه‌رو می‌شود و در نتیجه حاصل کارش اشتباه خواهد شد.

حالا سازندگان Rust با غیرقابل تغییر کردن متغیّرها سعی داشتند که تا حد امکان ایمنی داده‌ها را در برنامه‌های هم‌روند تضمین کنند. اینطوری هیچ کدام از thread ها نمی‌توانند داده‌ی اصلی‌را عوض کنند, پس اشکالی در کار بقیه‌ی threadها پیش نمی‌آید.

امیدوارم که نوشته‌های این جلسه واضح باشند. اگر بخشی‌را متوجّه نشدید یا به نظرتان گنگ توضیح داده بودم در بخش نظرات بگویید تا نوشته‌را اصلاح کنم.

در جلسه‌ی بعد با cargo آشنا می‌شویم و بعد نحوه‌ی تعامل با کاربر را از طریق command line یاد خواهیم گرفت.

نوشته آموزش زبان برنامه‌نویسی Rust – قسمت ۱: شروع کار با متغیّرها و ثوابت اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

آموزش زبان برنامه‌نویسی Rust – قسمت ۰: معرفی و شروع به کار

وقتی صحبت از برنامه‌نویسی سیستم می‌شود همه یاد زبان C می‌افتند. ولی الان چند سالی هست که یک زبان بسیار قدرتمند به نام Rust ساخته شده. زبانی که بسیاری از مشکلات زبان C را ندارد. مشکلاتی که برای نوشتن برنامه‌های مورد نیاز صنعت امروز دردسر شده اند و هزینه‌هارا به شکل سرسام‌آوری افزایش داده اند.

از آنجایی که این زبان بسیار قوی و پرکاربر که برای دوسال در نظرسنجی سالیانه استک‌اورفلو به عنوان موردعلاقه‌ترین زبان برنامه‌نویسی مشخص شده در ایران مهجور مانده, تصمیم گرفتم که یک آموزش فارسی و جامع برای این زبان تهیه کنم. و چه جایی بهتر از ویرگول؟

از آنجایی که زبان Rust در خیلی از مفاهیم با زبان‌های دیگر تفاوت‌های کلّی یا جزئی دارد, یادگیری آن کار بسیار جالب و چالش‌برانگیزی است.

تنها نکته‌ای که باقی می‌ماند این است که من تمام تلاشم‌را برای توضیح مباحث می‌کنم, امّا به صورت پیش‌فرض مطلب‌را برای افرادی توضیح می‌دهم که آشنایی اوّلیّه با برنامه‌نویسی دارند. بنابراین اگر تا به حال برنامه‌نویسی نکرده‌اید ممکن است کمی گیج شوید.

تاریخچه

زبان برنامه‌نویسی Rust توسط یکی از مهندسان موزیلا به نام Graydon Hoare معرفی شد. در حقیقت این زبان بخشی از یکی از پروژه‌های شخصی ایشان بود. بنیاد موزیلا از سال ۲۰۰۹ حامی مالی این زبان شد.

اوّلین نسخه‌ی پایدار این زبان در سال ۲۰۱۵ منتشر شد.در tحال حاضر نسخه‌ی ۱٫۲۷٫۱ این زبان در دسترس عمومی قرار دارد.

این زبان متن‌باز است و تحت لایسنس MIT کد منبعش در اختیار همگان است.

ویژگی‌ها

برنامه‌های نوشته شده به زبان Rust باید ترجمه(compile) شوند. به همین دلیل سرعت اجرای آن‌ها از برنامه‌های مشابه مفسری(مثل پایتون) بیشتر است.

وبسایت رسمی این زبان ویژگی‌های زیر را به عنوان موارد شاخص برای این زبان ذکر کرده است(از آنجایی که خیلی از موارد معادل فارسی خوبی نداشتند همان توضیح انگلیسی‌را آوردم. اگر متوجّه نشدید در بخش نظرات بپرسید):

  • سرعت بسیار بالا
  • zero-cost abstractions
  • move semantics
  • guaranteed memory safety
  • threads without data races
  • trait-based generics
  • pattern matching
  • type inference‌
  • minimal runtime
  • efficient C bindings

بسیاری از تفاوت‌های زبان Rust با دیگر زبان‌ها به این خاطر است که سازندگان آن می‌خواستند تا جای ممکن ایمنی در هنگام کار با thread ها را تضمین کنند.

نصب Rust

برای شروع باید Rust را نصب کنیم. Rust به‌وسیله‌ی rustup نصب می‌شود. ابزار command lineی که نسخه‌های مختلف Rust و ابزارهای مورد نیاز آن‌را مدیریت می‌کند.

نصب Rust کار بسیار ساده‌ای است. الان با هم تمامی مراحل مورد نیاز برای نصب آن‌را می‌بینیم.

نصب Rust روی لینوکس یا macOs

برای نصب Rust اول از همه باید curl را داشته باشید. برای اینکه مطمئن شوید curl روی دستگاهتان نصب است, ترمینال‌را باز کنید. بعد دستور زیر را تایپ کنید:

اگر خروجی‌ای مشابه متن زیر مشاهده کردید یعنی curl روی سیستمتان نصب شده است(خروجی با توجّه به نسخه‌ی curl و سیستم عامل ممکن است متفاوت باشد):

در غیر این صورت با پیام خطای نصب نبودن نرم‌افزار روبه‌رو می‌شوید. اگر curl نصب نبود می‌توانید به سرعت آن‌را نصب کنید. برای مثال در سیستم‌عامل ابونتو می‌توانید دستور زیر را برای نصب سریع این برنامه در ترمینال اجرا کنید:

یا

حالا کافی است دستور زیر را اجرا کنید تا Rust به سادگی نصب شود:

این دستور اسکریپت rustup را نصب می‌کند. اگر تنظیمات پیش‌فرض‌را می‌خواهید, که پیشنهاد من هم این است, دیگر لازم نیست کار خاصی بکنید. بعد از دانلود اوّلیّه از شما نوع نصب پرسیده می‌شود(تصویر زیر).

با وارد کردن عدد ۱ و زدن دکمه‌ی Enter دیگر لازم نیست کاری بکنید. وقتی دانلود و نصب تمام شد, برای افزودن Rust به PATH دستور زیر را اجرا کنید:

اگر می‌خواهید در ترمینال موجود به Rust دسترسی داشته باشید دستور زیر را هم اجرا کنید:

البته همچنان امکان دارد که با بستن ترمینال کنونی دیگر به Rust دسترسی نداشته باشد که با یکبار ری‌استارت کردن همه‌چیز درست می‌شود.

به علاوه شما به یک لینکر هم نیاز دارید. اگر در حال حاضر توانایی کامپایل کردن برنامه‌های C را روی دستگاهتان دارید پس نیاز نیست کار دیگری بکنید. در غیر این صورت می‌توانید یک کامپایلر C نصب کنید.

نصب Rust روی ویندوز

شما برای استفاده از Rust نیازمند ابزار ساخت زبان C هستید. پس بهتر است ابتدا Visual Studio 2017 یا برنامه‌ای مشابه آن‌را نصب کنید و C++ support را فعّال کنید.

حالا از این آدرس بسته‌ی نصبی برنامه‌ی rustup را دانلود کنید و طبق پیام‌هایی که ظاهر می‌شوند آن‌را نصب کنید.

مراحل درست انجام شده اند؟

حالا که نصب انجام شده, زمان آن است که مطمئن شوید که همه‌چیز به درستی نصب شده اند. پس درون ترمینال یا cmd دستور زیر را اجرا کنید:

حالا اگر همه‌چیز روبه‌راه باشد, باید پیامی مشابه پیام زیر را ببینید:

با توجّه به زمانی که این مطلب‌را می‌خوانید ممکن است محتوای نمایش‌داده شده متفاوت باشد, امّا فرمت کلّی اینگونه خواهد بود.

و حالا سلام دنیا!

حالا می‌خواهیم با هم برنامه‌ی معروف hello world را در زبان Rust بنویسیم. یکی از جذّاب‌ترین بخش‌های زبان Rust این است که به صورت پیش‌فرض از فرمت UTF-8 استفاده می‌کند. به همین دلیل می‌توانید بدون انجام هیچ کار اضافی‌ای در آن فارسی بنویسید.

پس ما هم برنامه‌ی hello world را به زبان فارسی خواهیم نوشت.

برای شروع یک فایل به نام main.rs بسازید. حالا داخل آن کد زیر را بنوسید:

حالا برای اجرای برنامه با ترمینال یا cmd به مسیری که فایل قرار دارد بروید و دستور زیر را اجرا کنید:

با اجرای این دستور برنامه‌ی شما کامپایل می‌شود و فایل حاوی کد قابل اجرا در همان مکان ساخته می‌شود.

اگر از لینوکس یا macOs استفاده می‌کنید, برای اجرای برنامه دستور زیر را اجرا کنید:

اگر هم از windows استفاده می‌کنید دستور زیر را اجرا کنید:

و حالا از دیدن حاصل کارتان لذّت ببرید:

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

اگر سؤالی برایتان پیش آمده در بخش نظرات مطرح کنید. اگر در توانم بود کمکتان می‌کنم.

نوشته آموزش زبان برنامه‌نویسی Rust – قسمت ۰: معرفی و شروع به کار اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

تست A/B چه نقشی در بازاریابی محتوا دارد؟

این تست به شما کمک می کند تا بهترین رابط و تجربه کاربری را برای وب سایت یا اپلیکیشن خود انتخاب کنید. کارگاه « #تولید_محتوا ی تجاری» ویژه #مبتدیان bit.ly/2NH4JEP ویژه #متخصصین bit.ly/2zqYfqG #دانشگاه تهرا‏ن


نوشته تست A/B چه نقشی در بازاریابی محتوا دارد؟ اولین بار در مدرسه استارتاپ ایران. پدیدار شد.

گردآوری توسط ایده طلایی

SQL یا No-SQL مسئله اینست!

ابتدا بایدتوضیح بدم که ضمن نوشتن یک مقاله در مورد “بهینه سازی بانکهای اطلاعاتی SQL” که در آینده نزدیک منتشرخواهم کرد به این نتیجه رسیدم که این دو رو از هم جداکنم ،پس در ادامه به موارد استفاده از SQL و No-SQL میپردازیم.

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

موارد غیر مجاز استفاده از بانکهای اطلاعاتی رابطه‌ای:

  • صف:
    هرگونه ثبت داده برای ایجاد ترتیب پرادزش مثل ساختن یک جدول که داده ها پس از ثبت توسط یک یا چندین ورکر پردازش میشوند و بعد از انجام داده ها آپدیت میشوند مثل صف ارسال پیام ، SMS ، انجام کارهایی از این قبیل که بعد از انجام کار وضعیت انجام اونها ثبت میشود. زیرا پردازشهای موازی بهمراه خواندن و نوشتن همزمان باعث ازثبات خارج شدن/لگ شدن دیتابیس میشود و همچنین انباشت داده های قدیمیتری که پردازش شده اند کندی و افزایش سربار رو بهمراه خواهد داشت.
  • ذخیره‌ی داده‌های باینری حجیم:
    دیتابیسهای رابطه‌ای(Relational) برای ذخیره سازی داده های متنی/عددی مناسبتر میباشند و نقطه قوتشان در اصل رابطه ها و اتصالات سریع و منطقی بین مدلهای داده ای یا همان جداول است و از این رو برای نگهداری مستندات(Document) های حجیم (مثل تصاویر و ویدیوها و…) مناسب نیستند و برای این مدل از داده ها میبایست آنهارا در دیسک یا دیتابیس No-SQL ذخیره کرده و آدرس آنرا در بانک اطلاعاتی رابطه‌ای ذخیره نمایید.
  • ذخیره‌ی گراف:
    هر نوع شبکه‌ی پیچیده و اتصالات تو با خصیصه هایی که یال آن ارتباطات میباشند و انواع پیاده سازی تودر تو به صورت گراف بعلت انجام JOIN زیاد به شدت کل منابع سیستم رو قورت خواهد داد و کل دیسک را درگیر خواهدکرد (مثل دیتابیس یک شبکه اجتماعی/ارتباطی) که باید برای این نوع کاربرد از گراف دیتابیسها(Graph Databases) استفاده کنید مثل GraphQL , Neo4j…
  • الگوهای خواندن بیش از نوشتن:
    زمانیکه عملیات خواندن ردیفی یا همان واکشی داده ها کاربرد زیادی دارد و در کارکرد برنامه‌ی ما نوشتن بسیار ناچیزتر از خواندن است.
  • استفاده بعنوان key-value:
    هرگونه ذخیره سازی داده ها بدون نیاز به امکاناتSQL مانند ذخیره سازی داده های ساده شامل یک کلید و یک مقدار را روی SQL ذخیره نکنید(Redis چه بدی داشت که امتحان نکردی!)
  • ذخیره‌سازی انبوه (بالک):
    بالک ایمپورت (صرفاً خواندن و نوشتن) روی حجمهای چند ده میلیونی داده ها به شدت در بانکهای رابطه ای اختلال و لگ ایجاد خواهد کرد،و اگر نیازمند امکاناتSQLی و رابطه ای نیستیم مجاز به استفاده از بانکهای رابطه‌ای نیستیم ولی گاهی اوقات ممکن است که نیازمند این باشیم که یک بانک اطلاعاتی رابطه‌ای حجیم داشته باشیم که در آنصورت عملیات خلاصه سازی داده‌ها و پارتیشن بندی و… مطرح خواهد شد.


موارد مجاز استفاده از پایگاه‌های داده رابطه‌ای:

به طور خلاصه میتوان گفت:پایگاه‌های رابطه ای بعلت امکاناتی که در اختیار میگذارند گلوگاه‌های زیادی ایجاد میکنند و به نسبت No-SQLهای غیر رابطه ای کندتر عمل میکنند ویا همان مصرف منابع بیشتری دارند و هرگاه ما دلیل موجه و قدرتمندی برای استفاده از اونها نداریم نباید از اونها استفاده کنیم.

تراکنشها:

هر سیستمی که نیازمند تراکنشهای متعدد و انبوه میباشد. (تراکنش: به کوچکترین عملی که در سیستم انجام میشود و قابل تقسیم نمیباشد گویند مثل انتقال اعتبار از حساب یک مشتری به یک مشتری دیگر در بانک و…)

گزارشات پیشرفته داده ها برحسب کلیدهای خارجی:

هنگامیکه سیستم وابستگی زیادی به اتصال جداول با کلیدهای خارجی و واکشی و خلاصه گیری داده های موجود را دارد میبایست برای ساخت گزارشات متعدد از زبان ساختارمندی مثل SQL استفاده کنیم ، زیرا به راحتی میتوان در یک پرس و جو تمام موارد را باهم بدست آورد ولی در بانکهای غیر رابطه ای در صورتیکه کلید والد یا جدول دیگر را ذخیره کرده باشید ابتدا بعد از واکشی داده ها میبایست برحسب هر کلید یک کوئری دیگر برای خواندن جدول دیگر بزنید یا اگر پایگاه داده ی غیر رابطه ای شما از کوئریهای تودر تو پشتیبانی کند بازهم همین عمل تکرار خواندن در پس سیستم به ازای هر رکورد را انجام خواهد داد که هزینه‌ی زیاد الگوریتمیکی ایجاد خواهد کرد. از این گذشته نوشتن کوئری با SQL به شدت ساختارمند است و نوشتن و دیباگ کردن آنهم بسیار آسانتر است و قابلیت نگهداری آن بیشتر میباشد.

*داده‌های غیر حجیم:

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

به طور کلی اگر اپلیکیشن شما نیاز به کوئریهای بسیار پیشرفته یا نسبتا پیشرفته دارد و نیاز به تجزیه و تحلیل روزمره دارد و تمرکز کلی سیستم شما روی اجرای صحیح و ۱۰۰% مطمئن تراکنشهاست. یعنی نیازمند ACID هستید (مجموعه ای از کارکردها/خواص که یکپارچگی و ثبات و صحت تراکنشهای شمارا تضمین کند) میبایست در انتخاب پایگاه رابطه‌ای تردید نداشته باشید.

به طور کلی اگر چیزی مزید بر این موارد بر خوردم که فراموش کرده بودم به این مقاله اضافه خواهم کرد و اگر نکته ویا ایرادی در این خردمقاله میبینید ممنون خواهم شد که تذکر بدهید.

نوشته SQL یا No-SQL مسئله اینست! اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی

آموزش توابع scope در کاتلین : let ، run ، with ، also و apply

s

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

پیش نیاز این آموزش یاد داشتن extension function ها هست، میتونید از اینجا extension functionها رو یاد بگیرید.

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

متد run

https://gist.github.com/sajjadyousefnia/a742d2b7be22679e0d833ea31c221d7c

متد T.run

https://gist.github.com/sajjadyousefnia/bcee9d0db82253f80912897a0f6b0e43

متد with

https://gist.github.com/sajjadyousefnia/7f85da7083f03d7a8807e779140b87ae

متد T.apply

https://gist.github.com/sajjadyousefnia/65a7d3f514a96661ca44b024943d63fd

متد T.also

https://gist.github.com/sajjadyousefnia/94f68f66cddd946842f92519b2c6b05d

متد T.let

https://gist.github.com/sajjadyousefnia/10d9f342f0b4a93014b30d541b55172b

ا Scoping Functions

توابعی که می‌خوام در مورد اونا صحبت کنم ، T.run ، T.let ، T.also و T.apply هستن. که من به اونا Scoping Functions ( توابع قلمرو ) میگم، به این خاطر که وظیفه‌ی اصلی اونا اینه که توی تابع به ما توانایی به وجود آوردن قلمرو – اسکوپ – کوچکتری رو داخل بدنالبته یه نکته رو عرض کنم که معمولا مرز قلمروها رو با { و } مشخص می‌کنن .

ساده ترین راه برای نشون دادن مسئله، استفاده از تابع run هست.

https://gist.github.com/sajjadyousefnia/dc424bd4bc992348bc774682c5b9b42c

داخل تابع test با انجام این کار تونستیم یک اسکوپ مجزا به وجود بیاریم.داخل اسکوپ run، قبل از چاپ متغییر mood ، مقدارش رو برابر با I am happy قرار دادیم.

شاید این Scoping Functions توی نگاه اول زیاد به درد بخور به نظر نرسه، ولی یه قابلیت مهم دیگه ای هم داره، و اون اینه که میتونه چیزی رو return کنه.

کد پایینی که از این قابلیت استفاده کرده خیلی شسته رُفته‌تر شده، و دیگه نیازی نیست که برای انجام کار موردنظرمون دوبار از متد show استفاده کنیم.

https://gist.github.com/sajjadyousefnia/a85a3398b85145d50e6272cf1f7cb037

انواع Scoping functions

حالا برای این که Scoping Function ها رو بهتر متوجه بشیم، می‌تونیم به سه روش زیر اونا رو دسته بندی کنیم. و با سه ملاک از هم دیگه تمییزشون بدیم.

۱- تابع معمولی یا extension function

توابع with و T.run توی نگاه اول خیلی شبیه هم هستن. همونطور که پایین می‌بینیم، دارن کار یکسانی رو انجام میدن.

https://gist.github.com/sajjadyousefnia/04d8eaeab80ab11586189eb572bfd182

اما در حقیقت کمی متفاوت هستن، و فرقشون اینه که with یک تابع معمولی هست، در حالی که T.run یک extension function هست.( حتی اگه به شکل extension function به کار نره )

به متدهای اونا که اول مقاله نوشته شده، توجه کنید تا بهتر متوجه بشید.

خب حالا یه سوالی پیش میاد و اون اینکه مزیت هر کدوم چیه؟

حالا تصور کنید که احتمال این باشه که webview.settings تهی یا همون null باشه، حالا اون توابع به شکل پایینی درمیان.

https://gist.github.com/sajjadyousefnia/307530313c346b721b16ae69e9fbdcb7

خب همونطور که دیدین حتما متوجه شدین که توی این مورد استفاده از T.run کار بهتری به نظر بهتر میرسه، چون قبل از اینکه بخوایم ازش استفاده کنیم، میتونیم بررسی کنیم که تهی هست یا نه؟

۲- آرگومان this و آرگومان it

خب، اول باید بررسی کنیم که this و it هر کدوم چی هستن و کجا استفاده میشن؟

آرگومان this

از this برای نشون دادن receiver یا همون آبجکت دریافت کننده‌ی فعلی استفاده میکنیممنظور از دریافت کردن، دریافت کردن this هست و در دو جا برابر با دو چیز تقریبا مختلف هست :

۱- توی یک کلاس، this یعنی آبجکت فعلی که از جنس این کلاس ساخته شده.

۲- توی یک extension function یا یک function literals with reciever که از ترکیب لامبدا و extension function ساخته میشن this عبارتست از آخرین پارامتر دریافت کننده‌ای که مربوط به سمت چپ نقطه هست و از جنس عبارت سمت چپ نقطه هم هست،

اگه به مثال توجه کنید بهتر متوجه منظورم میشید:

https://gist.github.com/sajjadyousefnia/f4d100c3ff7dc29499fb031f47305a9c

توی extension function بالا متغییر ، عبارت adult چاپ میشه. چون همونطور که گفتم، این متغییر هست که به عبارت سمت چپ نقطه فرستاده شده. برای خسته کننده نبودن، this توی function literal ها رو دیگه توضیح نمیدم و اینجا هم نیازی به function literal نداریم.

آرگومان it

خیلی پیش میاد که یک لامبدا داشته باشیم که فقط یک پارامتر داشته باشه.

در این صورت اگر که کامپایلر بتونه امضا یا همون پارامتر رو تشخیص بده، میتونیم فلش لامبدا رو حذف کنیم و به جای استفاده از اسم پارامتر، از it استفاده کنیم.

https://gist.github.com/sajjadyousefnia/2e5e06495aa683d96be81caf10b0de33

خب، حالا اگه به متدهای ابتدای مقاله نگاهی بندازید حتما متوجه میشید که چه جاهایی از this و چه جاهایی از it به عنوان آرگومان و پارامتر استفاده میشه.
نکته : اگه کلاسهای تودرتو داشته باشیم، this برابر با داخلی‌ترین آبجکت توی کلاس هست.

https://gist.github.com/sajjadyousefnia/0bf0868731861bcfe4340528e2b5b3ac

اگه یه نگاهی به توابع T.run و T.let بندازیم، حتما متوجه میشید که همه‌ی ویژگی هاشون به جز یکی یکسانه، در واقع، اون ویژگی ای که باعث تمایز این دوتا میشه، نوع آرگومانی که دریافت میکنن هست. اگه به کد پایینی نگاه کنید می‌بینید که ظاهرا هر دو منطق کاملا یکسانی دارن،البته در ادامه بیشتر توضیح میدم.

https://gist.github.com/sajjadyousefnia/78ee6ebf71853a09ed129a178c8d4703

اگه signature یا همون پارامتر تابع T.run رو بررسی کنید، حتما متوجه این میشید که با استفاده از ().block :T داره صرفا یک Extension Function رو ایجاد میکنه. به همین دلیل هست که T داخل قلمروی مورد نظر میتونه با استفاده از this فراخوانی و استفاده بشه. توی کدنویسی هم که اکثر اوقات میشه this رو حذف کرد. به همین خاطر توی عبارت بالا به جای میشه به جای ${this.length} داخل println فقط $length رو قرار داد. که من اسم این کار رو this as argument ( استفاده از this به عنوان آرگومان ) میگذارم.

اگه به T.let توجه کنید میبینید که یک آرگومانی به شکل block:T داره به تابع فرستاده میشه. برای همینه که میشه داخل let ، اون رو با استفاده از it فراخوانی کرد و مورد استفاده قرار داد. که من اسم این قابلیت رو it as argument میگذارم.

ممکنه که اینجوری نتیجه‌گیری کرده باشید که چون ما میتونیم توی T.run اسم پارامترمون رو نبریم، حتی از this هم میشه استفاده نکنیم، ولی توی T.let در خلاصه‌ترین حالت ممکن باید از it استفاده کنیم (یا به قولی T.run از اون یکی implicit تره) ——> پس حتما استفاده از T.run بهتر خواهد بود. در حالی که اینطور نیست! به دلایل زیر استفاده از T.let بهتره :

  • توی T.let بهتر میشه این مسئله رو متوجه شد که این پارامتری که می‌بینیم، عایا مال این کلاس ( تابع یا property ) هست یا (تابع یا property ) کلاس دیگه.( مثلا در حالتی که کلاسهای تودرتو داشته باشیم )
  • توی eventهایی که this قابل حذف شدن نیست ( مثلا فرض کنید که داخل همون اسکوپ let یا run بخوایم اون متغییر رو به عنوان پارامتر یک متد مورد استفاده قرار بدیم )، استفاده از it به جای this به نظر بهتر و کوتاه‌تر میرسه.
  • به لحاظ نام‌گذاری و اینا استفاده از it بهتره، چون می‌تونیم به جای it ، داخل اسکوپ داخلی از یک اسم دیگه براش استفاده کنیم. به مثال زیر توجه کنید :
https://gist.github.com/sajjadyousefnia/c975a52c5acbdd88136ab80e2fcd93c5

۳- جنس چیزی که return میشه از نوع this باشه یا از جنس دیگری

حالا یک نگاهی به T.let و T.also میندازیم. اگه به اسکوپ داخلی تابع نگاهی بندازیم، ظاهرا هر دو یک کار رو انجام میدن.

https://gist.github.com/sajjadyousefnia/1a55699e16e78f60a4c97352c3e5e005

اما کمی با هم متفاوتن، این تفاوت در چیزی که return میکنن هست. T.let یک مقدار از هر نوعی رو میتونه return کنه ولی T.also صرفا متغییری از نوع T رو return میکنه.

هر دوی این توابع زنجیره‌ای به درد بخور هستن و کاربرد زیادی توی توابع زنجیره‌ای دارن، منتها بایستی که هر کدوم توی توابع زنجیره‌ای به شیوه‌ی درستی مورد استفاده قرار بگیرن. چون در T.let ، متغییر هربار دچار تغییر میشه ولی توی همه‌ی T.also ها از یک this یکسان استفاده میشه، به مثال‌های زیر توجه کنید :

https://gist.github.com/sajjadyousefnia/6ca462ef321b8c2383db10d88fa525cc

اینطور به نظر میرسه که بهتره به جای زنجیری نوشتن T.also همه رو داخل یک تابع بنویسیم، ولی اگه عمیق‌تر فکر کنیم متوجه میشیم که این حالت زنجیری سه مزیت داره :

۱- باعث میشه که بهتر بتونیم یک پروسه رو به قسمت‌های کوچکتر تقسیم کنیم.

۲- باعث میشه که بتونیم قبل از خروجی، داده‌ها رو بهتر مدیریت کنیم و احتمال خطا کاهش پیدا میکنه.

با ترکیب زنجیری متدهای مختلف میتونیم یک تابع قدرتمندتر و در عین حال کوتاه‌تر داشته باشیم. مثل پایینی :

https://gist.github.com/sajjadyousefnia/115c5228b3433904d2d23e7ed01a7567

با استفاده از سه ویژگی‌ای که گفته شد، میشه عملکرد یک تابع اسکوپ رو به خوبی فهمید. در ضمن ویژگی‌های ‌T.apply رو که قبل نگفتم به صورت زیر هست :

۱- یک extension function هست.

۲- این متد، this رو به عنوان آرگومان میفرسته.

۳-این متد this رو return میکنه.

ک میتونیم ازش به صورت زیر استفاده کنیم :

https://gist.github.com/sajjadyousefnia/42aab8f7b39667e8e5e1cf65c15b6ea1

یا میتونیم با استفاده ازش یک تابع رو به شکل زنجیری دربیاریم.

https://gist.github.com/sajjadyousefnia/c313a684bd679b7b235b396fdd02dc00

انتخاب تابع مناسب

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

امیدوارم خوب نوشته باشم، اگه دوست داشتید نظرتون رو بفرمایید.

نوشته آموزش توابع scope در کاتلین : let ، run ، with ، also و apply اولین بار در ویرگول پدیدار شد.

گردآوری توسط ایده طلایی