<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6325922</id><updated>2024-09-27T01:56:07.797+03:30</updated><category term="شخصی"/><category term="لینوکس"/><category term="برنامه نویسی"/><category term="خط فرمان"/><category term="اینترنت"/><category term="شبکه"/><category term="اوبونتو"/><category term="خبر"/><category term="cpp"/><category term="جاوااسکریپت"/><category term="جشن انتشار"/><category term="گوگل"/><category term="Qt"/><category term="ایران"/><category term="بانک اطلاعاتی"/><category term="تست"/><category term="سیاست"/><category term="فدورا"/><category term="نرم افزار"/><category term="کیوت"/><category term="NoSQL"/><category term="linux"/><category term="mongodb"/><category term="tdd"/><category term="انتخابات"/><category term="تصاویر"/><category term="جالب انگیز"/><category term="فایرفاکس"/><category term="مونگو"/><category term="پروکسی"/><category term="C#"/><category term="cmake"/><category term="debug"/><category term="firewall"/><category term="gdb"/><category term="grep"/><category term="macro"/><category term="rvalue"/><category term="rvalues"/><category term="ssh"/><category term="tor"/><category term="vi"/><category term="اپن سوزه"/><category term="تقویم تاریخ"/><category term="تور"/><category term="توییتر"/><category term="جامعه"/><category term="سال نو"/><category term="شعر"/><category term="ف.ی.ل.ت.ر.ی.ن.گ"/><category term="فایروال"/><category term="موسیقی"/><category term="هک"/><category term="پاریس"/><category term="پایتون"/><title type='text'>وب نوشت های مرد مرده</title><subtitle type='html'>گاه نوشت های من در ارتباط با تجربیات روزمره</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='https://blog.deadman.ir/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default?start-index=26&amp;max-results=25'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>120</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6325922.post-689764519892627037</id><published>2020-08-30T19:23:00.001+04:30</published><updated>2020-08-30T19:23:33.684+04:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="firewall"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="شبکه"/><category scheme="http://www.blogger.com/atom/ns#" term="فایروال"/><title type='text'>اعمال تغییرات بر روی فایروال در CentOS  با استفاده از firewall-cmd</title><content type='html'>&lt;p dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj08m1AUPoRHUknRGlZI30-qOC1TBaxZ6CNHWfi6kH8eueUsHPAeGz9GSAU52At_dm5XkEhQ1wRICm2t0DVkRZhK5ZupaZmmgzcaT1lVjucu6K1Tt2OZfs5qFbPv2eac5QFXGKeRQ/s800/firewall.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;400&quot; data-original-width=&quot;800&quot; height=&quot;256&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj08m1AUPoRHUknRGlZI30-qOC1TBaxZ6CNHWfi6kH8eueUsHPAeGz9GSAU52At_dm5XkEhQ1wRICm2t0DVkRZhK5ZupaZmmgzcaT1lVjucu6K1Tt2OZfs5qFbPv2eac5QFXGKeRQ/w512-h256/firewall.png&quot; width=&quot;512&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&amp;nbsp;&lt;p&gt;&lt;/p&gt;&lt;p dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;برای اعمال تغییرات بر روی فایروال با استفاده از firewall-cmd در CentOS میتونیم به صورت زیر عمل کنیم:&lt;/p&gt;

&lt;p dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;۱. وضعیت فعلی قوانین فایروال&lt;/p&gt;

&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ sudo firewall-cmd --list-all&lt;/pre&gt;
&lt;/div&gt;

&lt;p dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;۲. اضافه کردن یک سرویس&lt;/p&gt;

&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ sudo firewall-cmd --add-service=http&lt;/pre&gt;
&lt;/div&gt;

&lt;p dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;۳. اضافه کردن یک پورت &lt;/p&gt;

&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ sudo firewall-cmd --add-port=1234/tcp
$ sudo firewall-cmd --add-port=1234/udp
&lt;/pre&gt;
&lt;/div&gt;

&lt;p dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;۴. برای ذخیره تغییرات اعمال شده از سوییچ --premanent استفاده میکنیم:&lt;/p&gt;

&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ sudo firewall-cmd --premanent --add-port=1234/tcp&lt;/pre&gt;
&lt;/div&gt;

&lt;p dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;&amp;nbsp;&lt;br /&gt;&lt;/p&gt;

</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/689764519892627037/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2020/08/centos-firewall-cmd.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/689764519892627037'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/689764519892627037'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2020/08/centos-firewall-cmd.html' title='اعمال تغییرات بر روی فایروال در CentOS  با استفاده از firewall-cmd'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj08m1AUPoRHUknRGlZI30-qOC1TBaxZ6CNHWfi6kH8eueUsHPAeGz9GSAU52At_dm5XkEhQ1wRICm2t0DVkRZhK5ZupaZmmgzcaT1lVjucu6K1Tt2OZfs5qFbPv2eac5QFXGKeRQ/s72-w512-h256-c/firewall.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-3628230438857469887</id><published>2020-02-20T15:42:00.001+03:30</published><updated>2020-02-20T15:43:51.627+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="cpp"/><category scheme="http://www.blogger.com/atom/ns#" term="rvalue"/><category scheme="http://www.blogger.com/atom/ns#" term="rvalues"/><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><title type='text'>نکاتی کوتاه در C++: rvalues</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ8xGwhqyPqVolT4BYPzozD1Zjz9rWC70WobGTBL8ckSiqCH2YZBZev7pmJPFy2yvn9Csm0eKmNh6WytFHIjfXqEOLekI-pvP6td2BlRcQoJQpS6cyWKejahs6xQJSRQ3_mT41jg/s1600/cpp-tips_rvalues.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;400&quot; data-original-width=&quot;800&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ8xGwhqyPqVolT4BYPzozD1Zjz9rWC70WobGTBL8ckSiqCH2YZBZev7pmJPFy2yvn9Csm0eKmNh6WytFHIjfXqEOLekI-pvP6td2BlRcQoJQpS6cyWKejahs6xQJSRQ3_mT41jg/s400/cpp-tips_rvalues.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
توی این سری میخوام نکاتی رو در مورد برنامه نویسی به زبان C++ بطور مختصر و با زبان ساده توضیح بدم. &lt;/blockquote&gt;
تو اولین پست از این سری میخوام راجع به rvalue ها در c++ بنویسم. یکی از مواردی که برای خیلی از برنامه‌نویس‌ها ممکنه مقداری نامفهوم باشه.&lt;br /&gt;
&lt;br /&gt;
مفهوم rvalue ها در c++ به مقادیر موقتی گفته میشه که به طور معمول در سمت راست یک expression قرار میگیرن. میشه اونها رو به یک متغیر اختصاص داد، اما نمیشه مقداری رو به اونها تخصیص داد. مقادیر عددی یا فراخوانی توابع مثال هایی از استفاده از rvalue ها در c++ هستش. تو مثال زیر `1` و `foo()` مثال هایی از rvalue هاست که برای مقداردهی اولیه متغیرهای `a` و `b` استفاده شده. به `a` و `b` در این مثال `lvalue` گفته میشه.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;int a = 1;
int b = foo();
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
همچنین مثال های زیر نمونه هایی از مقدادهی نادرست بوده که امکان موقع کامپایل با خطا روبرو میشه:&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;1 = c; // error
foo() = d; // error
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
حالا چطور تعیین میکنیم که یک متغیر موقتی هستش؟‌ بطور کلی مقداری رو موقتی میدونیم که متغیری به اون مرتبط نشده باشه.&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;Int bar = 1; // bar is a name, so it is an lvalue.
2; // 2 is an integer literal, it has no name (no identifier). It&#39;s an rvalue.
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
مورد دیگه ای که میتونیم برای تشخیص rvalue ها استفاده کنیم اپراتور آدرس `&amp;amp;` هستش. توی c++ نمیتونیم آدرس rvalue ها در حافظه رو بگیریم.&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;int a = 1;
&amp;amp;a; // Works, address of a stack-allocated variable.
&amp;amp;1; // Error, 1 is an integer literal.
&amp;amp;foo(); // Error, cannot take address of the temporary result of a function call.
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
یکی از جاهایی که rvalue ها به ما کمک میکنن move semantics هستش که تو پست های بعدی راجع بهش صحبت میکنیم.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/3628230438857469887/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2020/02/c-rvalues.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/3628230438857469887'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/3628230438857469887'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2020/02/c-rvalues.html' title='نکاتی کوتاه در C++: rvalues'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJ8xGwhqyPqVolT4BYPzozD1Zjz9rWC70WobGTBL8ckSiqCH2YZBZev7pmJPFy2yvn9Csm0eKmNh6WytFHIjfXqEOLekI-pvP6td2BlRcQoJQpS6cyWKejahs6xQJSRQ3_mT41jg/s72-c/cpp-tips_rvalues.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-7803737319373029020</id><published>2020-01-19T15:08:00.001+03:30</published><updated>2020-01-19T16:54:30.172+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="cpp"/><category scheme="http://www.blogger.com/atom/ns#" term="macro"/><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><title type='text'>نکاتی در مورد ماکرو ها در سی / سی ++</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHzGzHRJZ6S4U7I6syK1XUPnQObEEMA2Ajd2DggjZ8OENSumrOLx8V7LLQpjEocSBnOQFejYMmZ5jjAEJHLQDDad3gCkKCzNxyqzUIsad_zZ5uc8QqzZDisuP89uvuSbALqfi6OA/s1600/cpp-macro.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;400&quot; data-original-width=&quot;800&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHzGzHRJZ6S4U7I6syK1XUPnQObEEMA2Ajd2DggjZ8OENSumrOLx8V7LLQpjEocSBnOQFejYMmZ5jjAEJHLQDDad3gCkKCzNxyqzUIsad_zZ5uc8QqzZDisuP89uvuSbALqfi6OA/s400/cpp-macro.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;خوب باید اعتراف کنم بعد از این همه سال که دارم سی پلاس پلاس کد میزنم بازم کلی نکته راجع به این زبان باستانی وجود داره که ازشون بی خبرم و هر از گاهی با یه سری از اونها روبرو میشم. یکی از این موارد رو که امروز توی کار بهش برخوردم یه سری استفاده خاص از ماکروها هستش.&lt;/div&gt;&lt;h2 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;تعریف ماکرو&lt;/h2&gt;&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;طبق تعریف ارائه شده در مستندات GCC، ماکرو در حقیقت تکه کدی هستش که براش نامی رو در نظر میگیریم. هرجا از برنامه که از این نام استفاده کرده باشیم کامپایلر قبل از شروع به کامپایل اون رو با تکه کد مربوطه جایگزین میکنه.&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;ما بطور کلی دو نوع استفاده از ماکرو داریم:&lt;/div&gt;&lt;ul dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;&lt;li&gt;نوع اول object-like macros: که برای مشخص کردن مقادیر استفاده میکنیم.&lt;/li&gt;
&lt;li&gt;نوع دوم function-like macros: ماکرو هایی که برای جایگزاری یه قطعه کد در برنامه استفاده میشن.&lt;/li&gt;
&lt;/ul&gt;&lt;h2 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;موارد معمول استفاده از ماکروها&lt;/h2&gt;&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;حالا که یه تعریف کلی از ماکرو ارائه دادیم بریم سراغ استفاده های مختلف اون در برنامه ها:&lt;/div&gt;&lt;h3 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;۱. تعریف مقادیر ثابت پیش‌فرض&lt;/h3&gt;&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;یکی از استفاده هایی که از ماکرو میشه اینه که مقادیر ثابت رو در بخشی از برنامه تعریف کنیم و از اون در جاهای مختلف برنامه استفاده کنیم:&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;brush:cpp&quot;&gt;#define PORT 8080
#define LOG_PATH &quot;/path/foo/bar&quot;
#define DEBUG_MODE 1
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;با تعریف این مقادیر ثابت در بخشی از برنامه و استفاده از نام ماکرو در بقیه برنامه دیگه لازم نیست برای تغییر یک متغیر کد برنامه رو شخم بزنیم هر استفاده ای رو اصلاح کنیم و فقط محل تعریف ماکرو رو اصلاح میکنیم.&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;همچنین میتونیم با استفاده از pre-processor flags برنامه رو با توجه به محیط مقصد کامپایل کنیم:&lt;/div&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/ramajd/bcac47747a9a1c4abf6d3d47c27f4a3c.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;کامپایل بصورت پیش‌فرض:&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;brush:bash&quot;&gt;$ gcc macro.c
$ ./a.out
compiled with: default flag 
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;تغییر MYFLAG در هنگام کامپایل:&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;brush:bash&quot;&gt;$ gcc -DMYFLAG=&#39;&quot;modified flag&quot;&#39; macro.c
$ ./a.out
compiled with: modified flag
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;۲. تعریف یک عملیات خاص توسط ماکرو&lt;/h3&gt;&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;گاهی برای انجام یک عملیات تکراری میتونیم بخشی از کد رو بصورت ماکرو بنویسیم و اون رو با ورودی‌های مختلف فراخوانی کنیم.&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;brush:cpp&quot;&gt;#define MAX(a,b) (a&amp;gt;b ? a : b)
#define EXISTS(array, vector)  (vector.find(value) != vector.end())
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;از اونجایی که کد مرتبط با ماکرو قبل از کامپایل با ماکرو جایگزین میشه سرعت برنامه در این حالت بالاتر میره، البته این مورد در مقایسه با توابع inline فرق خاصی نداره و تنها تفاوتش در اینه که توابع inline توسط کامپایلر مدیریت میشن ولی ماکرو ها توسط pre-processor مدیریت میشن.&lt;/div&gt;&lt;br /&gt;
&lt;h2 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;امکانات قابل استفاده در تعریف ماکرو ها&lt;/h2&gt;&lt;h3 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;۱. تبدیل متغیر ماکرو به متن&lt;/h3&gt;&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;در حالت عادی متغیرها / عبارت هایی رو که به ماکرو پاس میدیم اول محاسبه (evaluate) میشن و بعد به بدنه ماکرو ارسال میشن، ولی اگه بخوایم ورودی که به ماکرو ارسال شده رو داشته باشیم میتونیم با اضافه کردن کاراکتر `#` قبل از ورودی مورد نظر اون رو بصورت یک رشته داشته باشیم:&lt;/div&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/ramajd/2630550eec8041deab7863f0273d424b.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;خروجی برنامه:&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;brush:bash&quot;&gt;$ gcc macro2.c
$ ./a.out
Warning: x == 1
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;h3 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;۲. اتصال پارامترهای ماکرو&lt;/h3&gt;&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;بعضی مواقع لازم داریم تا مقداری رو به پارامترهای یک ماکرو اضافه کنیم در این موارد میتونیم این مقاریر رو با استفاده از `##` به هم متصل کنیم. برای بهتر فهمیدن مورد استفاده این امکان ماکرو اون رو با یک مثال توضیح میدیم:‌&lt;/div&gt;&lt;br /&gt;
&lt;script src=&quot;https://gist.github.com/ramajd/57f48261a668ab9b4599232b9af85a55.js&quot;&gt;&lt;/script&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;خروجی برنامه:&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;brush:cpp&quot;&gt;$ gcc macro3.c
$ ./a.out
quit command executed.
help command executed.
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;توی این مثال با استفاده از ماکرو `MKCMD` آرایه رو با name و function مربوطه بصورت خودکار initiate کردیم.&lt;/div&gt;&lt;br /&gt;
&lt;h3 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;۳. ماکرو با آرگومان های متغیر&lt;/h3&gt;&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;برخی مواقع لازمه که ماکرو ما تعداد متغیری ماکرو داشته باشه. برای این موضوع مثل تعریف توابع با پارامترهای متغیر نام ماکرو رو با `...` مشخص میکنیم و هنگام استفاده `__VA_ARGS__` رو بکار میبریم:&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;brush:cpp&quot;&gt;#define eprintf(…) fprintf (stderr, __VA_ARGS__)
...
eprintf (&quot;%s:%d: &quot;, input_file, lineno);  
// above line will be replaced with following:
//           fprintf (stderr, &quot;%s:%d: &quot;, input_file, lineno)
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;بعضی مواقع وقتی ماکرو ما خیلی پیچیده میشه میتونیم قبل از `...` یک نام رو برای بخش متغیر پارامترها تعیین کنیم و در ادامه از اون نام استفاده کنیم. فقط باید توجه کنیم که نمیتونیم این روش رو با همراه با __VA_ARGS__ استفاده کنیم.&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;brush:cpp&quot;&gt;#define eprintf(args...) fprintf(stderr, args)
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;ما همچنین میتونیم از پارامترهای با نام در کنار پارامترهای متغیر استفاده کنیم:&lt;/div&gt;&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;&lt;pre class=&quot;brush:cpp&quot;&gt;#define eprintf(format, …) fprintf (stderr, format, __VA_ARGS__)
&lt;/pre&gt;&lt;/div&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/7803737319373029020/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2020/01/cpp-macro-introduction.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/7803737319373029020'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/7803737319373029020'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2020/01/cpp-macro-introduction.html' title='نکاتی در مورد ماکرو ها در سی / سی ++'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHzGzHRJZ6S4U7I6syK1XUPnQObEEMA2Ajd2DggjZ8OENSumrOLx8V7LLQpjEocSBnOQFejYMmZ5jjAEJHLQDDad3gCkKCzNxyqzUIsad_zZ5uc8QqzZDisuP89uvuSbALqfi6OA/s72-c/cpp-macro.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-2779179962134909219</id><published>2020-01-19T14:54:00.002+03:30</published><updated>2020-01-19T15:17:36.820+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="cpp"/><category scheme="http://www.blogger.com/atom/ns#" term="debug"/><category scheme="http://www.blogger.com/atom/ns#" term="gdb"/><category scheme="http://www.blogger.com/atom/ns#" term="linux"/><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><category scheme="http://www.blogger.com/atom/ns#" term="لینوکس"/><title type='text'>اجرای برنامه با GDB و ذخیر لاگ در فایل</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDgWHbrmwCIQmv47j5GrQ_n-dG_kipyw-zz1wKS-1j6eZio7Bd-8M9IIq0h1I5YdMtnFsNsDoIk8ZkoE5infJbJan41UhyphenhyphenZmsB7bv2dZS-khd1Bdq286Zb4E4ylrcpje-35NQcqA/s1600/gdb.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;343&quot; data-original-width=&quot;800&quot; height=&quot;171&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDgWHbrmwCIQmv47j5GrQ_n-dG_kipyw-zz1wKS-1j6eZio7Bd-8M9IIq0h1I5YdMtnFsNsDoIk8ZkoE5infJbJan41UhyphenhyphenZmsB7bv2dZS-khd1Bdq286Zb4E4ylrcpje-35NQcqA/s400/gdb.jpeg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
یکی از ابزاری که در نبود IDE مخصوصا در محیط ریموت میتونه کمکمون کنه تا دلیل کرش کردن برنامه رو کشف کنیم استفاده مستقیم از خود GDB هستش.&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
برای مثال برنامه زیر رو که موقع اجرا خطا میده میخوایم با GDB دیباگ کنیم:&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
وقتی به صورت عادی برنامه رو اجرا کنیم با خطای زیر روبرو میشیم:‌&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ ./hello
Floating point exception
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;h3 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
اجرای برنامه بوسیله GDB&lt;/h3&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
برای اینکه برنامه رو با gdb اجرا کنیم کافیه تا اون رو به عنوان ورودی به GDB بفرستیم و بعد با دستور `run` برنامه رو اجرا کنیم:&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ gdb ./hello
(gdb) run
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgebOMVaAxQuHlKF_fI_vxBXw8SLtdg6EQvcKhoflc1Ys0EFUHzZ0I7RwEAiOB0i_M-eph5IJZftK8MDXh4JHlf-pmRTB1YdmTrA4lmesoah7ucw5Mi5dXDVxQCXgCrIvKjXnai3g/s1600/gdb2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;846&quot; data-original-width=&quot;1162&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgebOMVaAxQuHlKF_fI_vxBXw8SLtdg6EQvcKhoflc1Ys0EFUHzZ0I7RwEAiOB0i_M-eph5IJZftK8MDXh4JHlf-pmRTB1YdmTrA4lmesoah7ucw5Mi5dXDVxQCXgCrIvKjXnai3g/s400/gdb2.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
و موقع بروز خطا با استفاده از back trace به بررسی مشکل بپردازیم:&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;(gdb) bt
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJkR9iqaXumxK2o5mpbTviW8RrelKm-mSA_uE8BaKphT_XV9L2VCf6AI4N9xOpiu1JGYpX_R03hWOe81-WqRpb1BcOxGafrpyi7xozqHpO-6isQW4LZvmWF2dz3oFvoiVF4bvUIw/s1600/gdb3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;155&quot; data-original-width=&quot;1162&quot; height=&quot;52&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJkR9iqaXumxK2o5mpbTviW8RrelKm-mSA_uE8BaKphT_XV9L2VCf6AI4N9xOpiu1JGYpX_R03hWOe81-WqRpb1BcOxGafrpyi7xozqHpO-6isQW4LZvmWF2dz3oFvoiVF4bvUIw/s400/gdb3.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
همونطور که میبینید GDB اطلاعاتی راجع متدی که خطا در اون پیش اومده در اختیارمون قرار میده.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2 dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
ذخیره لاگ در فایل&lt;/h2&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
برای این منظور باید قبل از اجرای برنامه با دستور run تنظیمات لاگ مربوط به GDB رو بصورت زیر انجام بدیم:&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;(gdb) set logging on
(gdb) set logging file /path/to/log/file
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
همچنین برای مشاهده تنظیمات فعلی لاگ GDB از دستور زیر میتونیم استفاده کنیم:&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;(gdb) show logging
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/2779179962134909219/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2020/01/debug-with-gdb.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/2779179962134909219'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/2779179962134909219'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2020/01/debug-with-gdb.html' title='اجرای برنامه با GDB و ذخیر لاگ در فایل'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDgWHbrmwCIQmv47j5GrQ_n-dG_kipyw-zz1wKS-1j6eZio7Bd-8M9IIq0h1I5YdMtnFsNsDoIk8ZkoE5infJbJan41UhyphenhyphenZmsB7bv2dZS-khd1Bdq286Zb4E4ylrcpje-35NQcqA/s72-c/gdb.jpeg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-142142493310202019</id><published>2020-01-19T14:42:00.000+03:30</published><updated>2020-01-19T15:17:55.437+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="cmake"/><category scheme="http://www.blogger.com/atom/ns#" term="cpp"/><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><title type='text'>استفاده از PKG-CONFIG در CMAKE</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuc3SjagUyVAea6Ewy3vCfNBCvsuj0Gon75583mGHvyXrZMwy37fHV2oTmK80_uqSnuc3h8lFoUba_dukrW9ubRb19GhXQyZMli-WdPBfgZR8braNyuZeDq7X-FZc7fe9FSQVfBw/s1600/cmake.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;642&quot; data-original-width=&quot;1000&quot; height=&quot;256&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuc3SjagUyVAea6Ewy3vCfNBCvsuj0Gon75583mGHvyXrZMwy37fHV2oTmK80_uqSnuc3h8lFoUba_dukrW9ubRb19GhXQyZMli-WdPBfgZR8braNyuZeDq7X-FZc7fe9FSQVfBw/s400/cmake.jpeg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
از این به بعد تصمیم دارم تا اونجا که امکان داشته باشه مواردی رو که در طول کار روزانه باهاشون برخورد دارم رو اینجا لاگ کنم شاید بعدا دوباره لازمم شد.&lt;/div&gt;
&lt;/blockquote&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
جدیدا بخاطر سیاست شرکت جدید مجبور شدم از eclipse به Jetbrains CLion سوییچ کنم و این یعنی استفاده از CMAKE بجای build system داخلی eclipse. یکی از مواردی که تو روز اول کار با `CLio بهش برخوردم لینک کردن library های خارجی به برنامه خودم بود. برای اینکار از pkg-config استفاده کردم و بعد از نصب library مورد نظر، موارد زیر رو باید به فایل CMakeList.txt خودمون اضافه کنیم.&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:cpp&quot;&gt;find_package(PkgConfig REQUIRED)
pkg_check_modules(TITLE lib-name REQUIRED)

include_directories(${TITLE_INCLUDE_DIRS})
link_directories(${TITLE_LIBRARY_DIRS})
link_libraries(${TITLE_LIBRARIES})
&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/142142493310202019/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2020/01/pkg-config-in-cmake.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/142142493310202019'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/142142493310202019'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2020/01/pkg-config-in-cmake.html' title='استفاده از PKG-CONFIG در CMAKE'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuc3SjagUyVAea6Ewy3vCfNBCvsuj0Gon75583mGHvyXrZMwy37fHV2oTmK80_uqSnuc3h8lFoUba_dukrW9ubRb19GhXQyZMli-WdPBfgZR8braNyuZeDq7X-FZc7fe9FSQVfBw/s72-c/cmake.jpeg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-8927491188308602932</id><published>2020-01-19T13:41:00.002+03:30</published><updated>2020-01-19T13:41:40.102+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="tdd"/><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><category scheme="http://www.blogger.com/atom/ns#" term="تست"/><category scheme="http://www.blogger.com/atom/ns#" term="جاوااسکریپت"/><title type='text'>برنامه نویسی تست محور (TDD) - قسمت سوم یک مثال عملی</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQq1Xmk56GCtV7Vxe0hosZgMJtFNb9SYk5sTIxwC820fV_mm6oHI6SKsBCNQwm9XNHssnTcWMig2B3tmqXLuHE1rY7KaFgOu_H5dC23FgWn1V2c5B58ZELbRS-w0UQPvvvhTQy6Q/s1600/tdd3.jpeg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;237&quot; data-original-width=&quot;400&quot; height=&quot;236&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQq1Xmk56GCtV7Vxe0hosZgMJtFNb9SYk5sTIxwC820fV_mm6oHI6SKsBCNQwm9XNHssnTcWMig2B3tmqXLuHE1rY7KaFgOu_H5dC23FgWn1V2c5B58ZELbRS-w0UQPvvvhTQy6Q/s400/tdd3.jpeg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
حالا که با &lt;a href=&quot;https://devildarkness.blogspot.com/2020/01/test-driven-development-part-1.html&quot; target=&quot;_blank&quot;&gt;مفهوم برنامه نویسی تست محور&lt;/a&gt; آشنا شدیم و دیدیم که&lt;a class=&quot;md-inline-link&quot; href=&quot;https://devildarkness.blogspot.com/2020/01/test-driven-development-part-2.html&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt; چرخه این تکنیک به چه صورت کار میکنه&lt;/a&gt;، میخوایم باهم یک مثال عملی رو با استفاده از NodeJS پیاده سازی کنیم. در ابتدا پیش نیاز ها رو باهم آماده میکنیم، بعد میریم سراغ ساخت پروژه و در انتها مشغول نوشتن کد برنامه میشیم.&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;h2 class=&quot;md-block-header-three md-block-rtl&quot; style=&quot;text-align: right;&quot;&gt;
آماده سازی پیش نیاز ها&lt;/h2&gt;
خوب حالا میخوایم مفاهیم TDD رو توی یک برنامه NodeJS پیاده سازی کنیم. بیاید باهم همون مثال ماشین حساب رو که تو &lt;a href=&quot;https://devildarkness.blogspot.com/2020/01/test-driven-development-part-2.html&quot; target=&quot;_blank&quot;&gt;قسمت دوم&lt;/a&gt; باهم راجع بهش صحبت کردیم رو پیاده سازی کنیم. ما برای این برنامه از تکنولوژی های زیر استفاده میکنیم:&amp;nbsp;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;ul class=&quot;md-block-unordered-list-item md-block-rtl&quot;&gt;
&lt;li&gt;ماژول &lt;a class=&quot;md-inline-link&quot; href=&quot;https://mochajs.org/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Mocha&lt;/a&gt;: که از اون برای اجرای تست ها استفاده میکنیم. &lt;/li&gt;
&lt;li&gt;ماژول &lt;a class=&quot;md-inline-link&quot; href=&quot;http://chaijs.com/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;Chai&lt;/a&gt;: که یک کتابخانه مدیریت خطا ها هستش. &lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot;&gt;
برای پیاده سازی این مثال لازم داریم تا موارد زیر رو آماده داشته باشیم:‌&lt;/div&gt;
&lt;ul class=&quot;md-block-unordered-list-item md-block-rtl&quot;&gt;
&lt;li&gt;فریمورک NodeJS از قبل نصب شده باشه. ( از &lt;a class=&quot;md-inline-link&quot; href=&quot;https://nodejs.org/en/&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;اینجا&lt;/a&gt; میتونید برای نصب اقدام کنید )&lt;/li&gt;
&lt;li&gt;آشنایی با مفاهیم تست ( آشنایی اولیه، نیاز نیست تا در زمینه تست حرفه ای باشید ) مخصوصا مواردی که در قسمت های &lt;b class=&quot;md-inline-bold&quot;&gt;اول&lt;/b&gt; و &lt;b class=&quot;md-inline-bold&quot;&gt;دوم&lt;/b&gt; راجع بهشون صحبت کردیم. &lt;/li&gt;
&lt;li&gt;آشنایی پایه ای با NodeJS&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot;&gt;
اولین  مرحله برای شروع نصب Mocha هستش. Mocha یک فریمورک تست هستش که تو پروژه  های NodeJS ازش استفاده میشه. نصب Mocha خیلی سادس و شما به راحتی با دستور  زیر میتونید اون رو نصب کنید:&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot;&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ npm install -g mocha&lt;/pre&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
همچنین نیاز داریم کتابخانه Chai رو برای مدیریت خطا ها به پروژه خودمون اضافه کنیم. برای اینکار دستور زیر رو توی ترمینال وارد میکنیم:&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ npm install chai --save-dev
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;h2 style=&quot;text-align: right;&quot;&gt;
ساخت پروژه NodeJS&lt;/h2&gt;
برای این مثال ما از expressJS استفاده میکنیم. میتونید از Express Generator برای ساخت پروژه استفاده کنید. برای اینکار دستور زیر رو توی ترمینال وارد میکنیم: &lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ express tdd_test
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
حالا باید پیش نیاز ها رو نصب کنیم:&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ npm install
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
بعد از ساخت پروژه باید اسکرپت تست خودمون رو به فایل package.json اضافه کنیم.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:js&quot;&gt;...
&quot;scripts&quot;: {
     &quot;start&quot;: &quot;node ./bin/www&quot;,
     &quot;test&quot;: &quot;mocha test&quot;
},
...
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
با اینکار هر موقع که دستور npm test رو اجرا کنیم mocha اجرا میشه.&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
ما توی ساختار برنامه لاجیک برنامه رو توی پوشه controllers قرار میدیم و برای عملیات مورد نظرمون فایل operations.js رو توی این پوشه میسازیم. &lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;h2 style=&quot;text-align: right;&quot;&gt;
کدنویسی&lt;/h2&gt;
&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
از اونجا که Mocha بطور پیش فرض فایل های تست رو از مسیر test میخونه لازم داریم تا این پوشه رو تو شاخه اصلی پروژه بسازیم. داخل این پوشه فایل اصلی تست ها رو با اسم index.test.js میسازیم. این فایل مرجع همه تست های ما به حساب میاد و تست ها رو داخل اون import میکنیم. &lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
خوب حالا که ساختار برنامه رو آماده کردیم، بیاین مراحل چرخه تست رو که تو قسمت های &lt;a href=&quot;https://devildarkness.blogspot.com/2020/01/test-driven-development-part-1.html&quot; target=&quot;_blank&quot;&gt;اول&lt;/a&gt; و &lt;a href=&quot;https://devildarkness.blogspot.com/2020/01/test-driven-development-part-2.html&quot; target=&quot;_blank&quot;&gt;دوم&lt;/a&gt; یادگرفتیم روی این پروژه اعمال کنیم:&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;h3 style=&quot;text-align: right;&quot;&gt;
۱. نوشتن تست برای امکانات مورد نظر&lt;/h3&gt;
&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
داخل پوشه test یک پوشه جدید به نام controllers میسازیم. توی این پوشه تمامی تست های مربوط به کنترلرهای خودمون رو مینویسیم. حالا توی این پوشه فایلی به اسم controller.test.js رو میسازیم. اگه یادتون باشه هدف ما نوشتن تستی جهت متد add هستش، برای همین باید تمامی لاجیک مورد نیاز برای این تست رو اینجا پیاده سازی کنیم. اگه از قسمت قبل یادتون باشه لاجیک مورد نظر ما به این صورت هستش:&lt;br /&gt;
&lt;blockquote class=&quot;md-block-blockquote md-block-rtl&quot;&gt;
دریافت دو مقدار عددی از ورودی و بازگشت پاسخ صحیح در خروجی.&lt;/blockquote&gt;
خوب حالا کد تست رو بصورت زیر مینویسیم: &lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:js&quot;&gt;var expect = require(&#39;chai&#39;).expect;
var addOp = require(&#39;../../controller/operations&#39;).addOp;

describe(&#39;Math&#39;, ( ) =&amp;gt; {
   describe(&#39;#add function&#39;, ( ) =&amp;gt; {
      it (&#39;should returns the result number from the two arguments&#39;, ( ) =&amp;gt; {
         var result = addOp(1,2); 
         expect(result).to.equal(3);
      });
   });
});
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
همونطور که توی این کد میبنید ما اول اومدیم متد expect رو از کتابخونه تست خودمون (Chai) اضافه کردیم. بعد از اون امکاناتی رو که قراره بعدا پیاده سازی کنیم رو به برنامه تست اضافه کردیم. در ادامه توی کد تست خودمون اومدیم دو تا عدد ۱ و ۲ رو به متد add دادیم و انتظار داریم که عدد 3 رو که جواب صحیح هستش توی خروجی دریافت کنیم. تا اینجای کار تو این مرحله ما هیچ کدی رو پیاده سازی نکردیم و تنها تست مربوطه رو آماده کردیم.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;h3 style=&quot;text-align: right;&quot;&gt;
۲. اجرای تست و مشاهده خطا های دریافتی&lt;/h3&gt;
همونطور که دیدید تا اینجای کار ما هیچ کدی رو پیاده سازی نکردیم و فقط تست های مربوطه رو نوشتیم. حالا بیاین ببینیم با اجرای تست ها چه نتیجه ای دریافت میکنیم.&lt;br /&gt;
&lt;br /&gt;
برای اینکه تست رو اجرا کنیم ابتدا باید تست خودمون رو به فایل index.test.js اضافه کنیم. &lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:js&quot;&gt;require(&#39;./controllers/controller.test&#39;);
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
حالا با اجرای دستور زیر تست رو اجرا میکنیم: &lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ npm test
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTGqE-YFlweVF2EkkAifKmUNcU5mrrYfRR38pp9yNzQsYSgWy2lstVcmqeA5jbI0KAw75zVEwypVphJqb4xPO0bqakcOacaIE2o6EXAJqlEO4tRYda6fvY3YPyyEm_GbLGAIR5VQ/s1600/tdd31.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;802&quot; data-original-width=&quot;1098&quot; height=&quot;290&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTGqE-YFlweVF2EkkAifKmUNcU5mrrYfRR38pp9yNzQsYSgWy2lstVcmqeA5jbI0KAw75zVEwypVphJqb4xPO0bqakcOacaIE2o6EXAJqlEO4tRYda6fvY3YPyyEm_GbLGAIR5VQ/s400/tdd31.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
همونطور که میبینید با پیغام خطای TypeError: addOp is not a function روبرو شدیم. این بدین معناست که متد add هنوز به کنترلرمون اضافه نشده.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;h3 style=&quot;text-align: right;&quot;&gt;
۳. پیاده سازی ساختار امکانات مورد نظر:&lt;/h3&gt;
توی این مرحله ما میخوایم که ساختار امکاناتی رو که میخوایم پیاده سازی کنیم رو آماده کنیم. برای همین به سراغ فایل operations.js که قبلا ساختیم میریم و ساختار متد addOp رو بصورت زیر توی این فایل آماده میکنیم:&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:js&quot;&gt;exports.addOp = function (var1, var2) {
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
تو این مرحله ما فقط ساختار متد add رو آماده کردیم و به همین دلیل ما میتونیم این متد رو توی فایل تست import کنیم و دو تا ورودی رو بهش پاس بدیم.&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;h3 style=&quot;text-align: right;&quot;&gt;
۴. اجرای تست و مشاهده نوع خطا&lt;/h3&gt;
&lt;br /&gt;
حالا بیاین یک بار دیگه تست رو توی این مرحله اجرا کنیم: &lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ npm test
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
با اجرای تست میبینید که با خطای زیر روبرو میشیم:&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEgI05D8yPzD1d0Z6NZR5NdZiQnL79Acu5dd5996YICMvLWcQOmdXwICoU24ZvpJMyDJI3uYIU0f6Xnjq2tzyuo03Y-8dLaSCcGy5jvy8Q3k3WW-G4pOlsRDxhJEbzLMDcWOooLg/s1600/tdd32.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;806&quot; data-original-width=&quot;1078&quot; height=&quot;298&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEgI05D8yPzD1d0Z6NZR5NdZiQnL79Acu5dd5996YICMvLWcQOmdXwICoU24ZvpJMyDJI3uYIU0f6Xnjq2tzyuo03Y-8dLaSCcGy5jvy8Q3k3WW-G4pOlsRDxhJEbzLMDcWOooLg/s400/tdd32.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
۵. پیاده سازی لاجیک برنامه&lt;br /&gt;
توی این مرحله میخوایم تا متدی که قبلا ساختیم رو کامل کنیم و لاجیک برنامه رو بهش اضافه کنیم. با توجه به نیازمندی اعلام شده ما باید دو تا عدد رو از ورودی بگیریم، عمل جمع رو روی این دو عدد انجام بدیم و نتیجه رو توی خروجی برگردونیم:&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;
&lt;pre class=&quot;brush:js&quot;&gt;exports.addOp = function (var1, var2) { 
const num1 = isNaN(var1) ? 0 : var1;
const num2 = isNaN(var2) ? 0 : var2;

return num1 + num2;
};
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;h3 style=&quot;text-align: right;&quot;&gt;
۶. در نهایت پاس شدن تست ها&lt;/h3&gt;
تو این مرحله تنها کافیه تا تست رو مجددا اجرا کنیم و شاهد پاس شدن تست هایی که نوشتیم باشیم:‌&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI3NSIwxB4sWuDqKJyctQDjiH2H-RAOeRSjPexhD2teXiPwz6yrhZhyphenhyphenxzd8AnO7mZW4cNyEGHZm9JeTGgC4xZqGnUgGrv_6O746upo8xikoaM2hkD6GO9KhH13fMgcRFREOoP9vA/s1600/tdd33.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;488&quot; data-original-width=&quot;1042&quot; height=&quot;186&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI3NSIwxB4sWuDqKJyctQDjiH2H-RAOeRSjPexhD2teXiPwz6yrhZhyphenhyphenxzd8AnO7mZW4cNyEGHZm9JeTGgC4xZqGnUgGrv_6O746upo8xikoaM2hkD6GO9KhH13fMgcRFREOoP9vA/s400/tdd33.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
حالا که متد ما پیاده سازی شده و تمامی تست های مورد نیاز پاس شده، کار ما به پایان میرسه. اگه نیاز باشه متد جدیدی به کنترلر ما اضافه بشه ( مثلا عملیات تفریق ) ، می بایست کلیه این مراحل رو از اول برای متد جدید اجرا کنیم. در انتها تکنیک TDD به ما اطمینان میده که پیاده سازی این امکانات جدید مشکلی برای امکاناتی که قبلا پیاده سازی شده بودن ایجاد نکرده باشه.&lt;br /&gt;
&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
امیدوارم که از این سری آموزشی استفاده لازم رو برده باشید و با تکنیک برنامه نویسی تست محور (TDD) آشنا شده باشید. اگه دوست داشته باشید میتونید وبلاگ من رو کنید و مطالب جدیدی رو که تو زمینه تکنولوژی مینوسم مطالعه کنید.&lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/8927491188308602932/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2020/01/test-driven-development-part-3.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/8927491188308602932'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/8927491188308602932'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2020/01/test-driven-development-part-3.html' title='برنامه نویسی تست محور (TDD) - قسمت سوم یک مثال عملی'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQq1Xmk56GCtV7Vxe0hosZgMJtFNb9SYk5sTIxwC820fV_mm6oHI6SKsBCNQwm9XNHssnTcWMig2B3tmqXLuHE1rY7KaFgOu_H5dC23FgWn1V2c5B58ZELbRS-w0UQPvvvhTQy6Q/s72-c/tdd3.jpeg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-1292051134236152119</id><published>2020-01-19T12:15:00.003+03:30</published><updated>2020-01-19T12:21:25.590+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="tdd"/><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><category scheme="http://www.blogger.com/atom/ns#" term="تست"/><category scheme="http://www.blogger.com/atom/ns#" term="جاوااسکریپت"/><title type='text'>برنامه نویسی تست محور (TDD) - قسمت دوم یک مثال ساده</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; dir=&quot;rtl&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga4IOoTL8k56hqaYcSqwe9BGMRTUcvovi1DVF_Lfv8Skg57Cg1O9EpsC3eHb5iykQtLBPUyM_VpXxDq08Ws7X7eXqkcpbF7jvlWl57SSDUgi4dK_7Sh7w7ErrOI7VYRL3D7Ea1rA/s1600/tdd2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;448&quot; data-original-width=&quot;492&quot; height=&quot;291&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga4IOoTL8k56hqaYcSqwe9BGMRTUcvovi1DVF_Lfv8Skg57Cg1O9EpsC3eHb5iykQtLBPUyM_VpXxDq08Ws7X7eXqkcpbF7jvlWl57SSDUgi4dK_7Sh7w7ErrOI7VYRL3D7Ea1rA/s320/tdd2.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: right;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
در &lt;a href=&quot;https://blog.deadman.ir/2020/01/test-driven-development-part-1.html&quot; target=&quot;_blank&quot;&gt;قسمت اول&lt;/a&gt;
 درباره مفهوم برنامه نویسی تست محور، مراحل اون و مزایایی که برامون داره 
توضیح دادم. تو این قسمت با یک مثال ساده با این تکنیک آشنا میشیم. تو این 
پست هنوز درگیر کد نویسی نمیشیم اما با یک مثال ساده راجع به یه ماشین حساب
 سعی میکنیم تا با چرخه کار TDD آشنا بشیم. &lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;ابتدا بیایم با مفهومی که باید تست بشه آشنا بشیم...&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;separator&quot; dir=&quot;rtl&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh22o76lO6CQ8P748EAURdNKak0xG2psRmQKMjSsJadNzXTotP_z3YR5a6HsB-URQkAtJWmWSXBU4QmTZymanmsOKWo3ihKmN5oPY1-12vlNTVFYgV3mQmQr4dgQmkOoCmMD-6UmQ/s1600/tdd22.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;300&quot; data-original-width=&quot;282&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh22o76lO6CQ8P748EAURdNKak0xG2psRmQKMjSsJadNzXTotP_z3YR5a6HsB-URQkAtJWmWSXBU4QmTZymanmsOKWo3ihKmN5oPY1-12vlNTVFYgV3mQmQr4dgQmkOoCmMD-6UmQ/s1600/tdd22.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
فرض کنید که مشتری از ما 
درخواست داشته تا یه نرم‌افزار ماشین حساب براش تولید کنیم که فقط کار جمع 
رو انجام بده، نه بیشتر و نه کمتر. همونطور که میدونید خیلی راه برای توسعه
 همچین برنامه ای وجود داره. یه سری میان ساختار کلی برنامه رو آماده 
میکنن، یه سری دیگه اول به طراحی رابط کاربری مشغول میشن، و خیلی روش های 
دیگه که ممکنه به ذهنتون برسه. ما اینجا قصد داریم تا بخش لاجیک این برنامه
 رو با تکنیک TDD پیاده سازی کنیم. درسته که کار پیچیده ای نیست، اما باعث 
میشه تا با مفاهیم TDD بهتر آشنا بشیم و قدرت اون رو بهتر درک کنیم. &lt;/div&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
خوب حالا بیایم مراحل TDD رو که توی پست قبل باهاشون آشنا شدیم توی توسعه لاجیک برنامه خودمون بکار ببریم: &lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt; ۱. نوشتن تست برای امکانات مورد نظر&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
همونطور
 که گفتیم، اولین مرحله نوشتن تست هستش. نیازمندی ماشین حساب ما رو که به 
یاد دارید «عمل جمع». برای همین اسم متد تست خودمون رو «Add» میزاریم ( توی
 این مرحله لاجیک کامل برای تست متد Add رو پیاده سازی کنیم ). وقتی که 
برای عمل جمع متد تست مینویسیم، انتظار داریم که متد ما دو تا ورودی عددی 
رو به عنوان ورودی بگیره و مجموع این دو عدد رو توی خروجی برگردونه. &lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;۲. اجرای تست و مشاهده خطا&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
توی این مرحله به سادگی برنامه تست اجرا شده و از اونجایی که هیچ پیاده سازی انجام نشده مطمئنا با خطا روبرو میشیم. &lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;۳. پیاده سازی ساختار امکانات مورد نظر&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
توی
 این مرحله ما ساختار برنامه خودمون رو آماده میکنیم. ( هنوز کاری با لاجیک
 برنامه نداریم. ) متد Add رو با دو ورودی عددی و همچنین خروجی عددی تعریف 
میکنیم. &lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;۴. اجرای تست و مشاهده خطا&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
دوباره تست رو اجرا می‌کنیم. این دفعه خطایی که دریافت میکنیم مربوط به عدم تطبیق خروجی متد و مقدار مورد انتظار ما خواهد بود.&lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;۵. پیاده سازی لاجیک&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
توی
 این مرحله لاجیک مورد نیاز متد Add رو پیاده سازی میکنیم. این متد دو تا 
ورودی عددی رو گرفته و مجموع اونها رو توی خروجی بر میگردونه. &lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;۶. مشاهده پاس شدن همه تست ها&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
بالاخره
 به بهترین بخش کار رسیدیم. جایی که تست های ما پاس شده و خطایی رو توی 
کنسول مشاهده نمیکنیم. حالا با اطمینان میتونیم برنامه خودمون رو به مشتری 
تحویل بدیم و خیالمون راحت باشه که مطمئنا برنامه به درستی کار میکنه.&lt;/div&gt;
&lt;blockquote class=&quot;md-block-blockquote md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
به یاد داشته باشید که درصورت اعمال تغییرات نیاز داریم تا تمامی مراحل بالا رو دوباره روی برنامه اعمال کنیم.&lt;/blockquote&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
در &lt;a href=&quot;https://devildarkness.blogspot.com/2020/01/test-driven-development-part-1.html&quot; target=&quot;_blank&quot;&gt;قسمت اول&lt;/a&gt;
 راجع به مفاهیم برنامه نویسی تست محور صحبت کردیم و توی این قسمت یک مثال 
ساده رو باهم بررسی کردیم، اگه تا اینجای کار از این سری مطالب خوشتون اومد
 میتونید تو &lt;a class=&quot;md-inline-link&quot; href=&quot;https://virgool.io/@r.a.majd/test-driven-development-part-3-f4f3o977ocai&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;قسمت سوم&lt;/a&gt; همراه با ما باشید تا این مثال رو بصورت عملی باهم پیاده سازی کنیم. &lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/1292051134236152119/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2020/01/test-driven-development-part-2.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/1292051134236152119'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/1292051134236152119'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2020/01/test-driven-development-part-2.html' title='برنامه نویسی تست محور (TDD) - قسمت دوم یک مثال ساده'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEga4IOoTL8k56hqaYcSqwe9BGMRTUcvovi1DVF_Lfv8Skg57Cg1O9EpsC3eHb5iykQtLBPUyM_VpXxDq08Ws7X7eXqkcpbF7jvlWl57SSDUgi4dK_7Sh7w7ErrOI7VYRL3D7Ea1rA/s72-c/tdd2.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-7188289178397713308</id><published>2020-01-19T12:08:00.000+03:30</published><updated>2020-01-19T12:10:52.025+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><category scheme="http://www.blogger.com/atom/ns#" term="تست"/><category scheme="http://www.blogger.com/atom/ns#" term="جاوااسکریپت"/><title type='text'>برنامه نویسی تست محور (TDD) - قسمت اول</title><content type='html'>&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; dir=&quot;rtl&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhacyEOZCZRyptUBGPHCU2EFRP_bmfJVvr0eEi7VbklhAN_jhyzfkliZNOqi_pQPD4KVCr2dWZBNBD3VhQBhL_HoSyfFvDO6HFMA41QI4uJhbG43iPDFHp_aTnbhQwWTfxe33vOmg/s1600/tdd1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;372&quot; data-original-width=&quot;475&quot; height=&quot;250&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhacyEOZCZRyptUBGPHCU2EFRP_bmfJVvr0eEi7VbklhAN_jhyzfkliZNOqi_pQPD4KVCr2dWZBNBD3VhQBhL_HoSyfFvDO6HFMA41QI4uJhbG43iPDFHp_aTnbhQwWTfxe33vOmg/s320/tdd1.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;
اینکه بخوایم برنامه نویس خوبی باشیم کار ساده ای نیست و باید همواره دانش 
خودمون رو بروز کنیم و در رابطه با تکنولوژی های جدید مطالعه داشته باشیم، 
وگرنه از جامعه عقب میمونیم و کم کم از دور رقابت خارج میشیم. این بروز 
بودن فقط محدود به فریمورک ها و زبان های برنامه نویسی و بانک های اطلاعاتی
 نمیشه، ما باید درباره تکنیک های جدید برنامه نویسی هم مالعه داشته باشیم 
تا بتونیم کیفیت کار خودمون رو هم بالا ببریم. یکی از این تکنیک های جدید 
که کمک میکنه تا سرعت بیشتری در توسعه داشته باشیم و هزینه توسعه پایین 
بیاد، برنامه نویسی تست محور یا Test Driven Development هستش که در اختصار
 بهش TDD میگن.&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;
تعریف برنامه نویسی تست محور&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
برنامه
 نویسی تست محور به تکنیکی از توسعه نرم افزار گفته می شود که در آن توسعه 
به چرخه های توسعه کوچکتر تقسیم شده و برای هریک از نیازمندی های هر بخش 
تست های مختلفی نوشته می‌شود. در ادامه توسعه امکانات نرم افزار محدود به 
پاس کردن این تست ها خواهد شد. &lt;/div&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
به
 بیان دیگر در برنامه نویسی تست محور ما ابتدا برای امکانات مورد نیاز 
خودمون تست مینویسیم و سپس کد مربوط به پاس کردن این تست ها توسعه داده 
میشه. &lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;
اهمیت تست ...&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
برای
 اینکه اهمیت برنامه نویسی تست محور برامون روشن بشه، اول باید اهمیت نوشتن
 تست رو درک کنیم. ما برنامه نویس ها معمولا زمان کافی برای نوشتن تست برای
 کد خودمون رو نداریم، بعضی از ما موقع توسعه فکر میکنیم که کدمون مشکلی 
نداره، خیلی وقت ها هم ممکنه محدودیت های زمانی که برای تحویل نرم‌افزار به
 کارفرما / مشتری داریم مانع از نوشتن تست برای کد ما بشه. اگه ما تست برای
 کد خودمون ننویسیم، باگها تو محیط مشتری خودشون رو نشون میدن و این اصلا 
موضوع جالبی نیست. ما باید سعی کنیم که به نوشتن تست ها به عنوان بخشی از 
توسعه نرم افزار عادت کنیم. نه بخاطر اینکه برخی نیازمندی ها این رو از ما 
میخوان بلکه بخاطر اینکه کد با کیفیت تری داشته باشیم نیاز هستش که تست های
 کاملی بنویسیم. این کار مطمئناً بتدا زمان بیشتری رو ازمون می‌گیره اما در
 نهایت باعث میشه تا باگ های کمتری داشته باشیم و کمتر مجبور به دوباره 
کاری باشیم. &lt;/div&gt;
&lt;h4 class=&quot;md-block-header-four md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;
شش قانون در توسعه تست محور&lt;/span&gt;&lt;/h4&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
میتونیم توسعه تست محور رو توی ۶ مرحله ساده زیر خلاصه کنیم: &lt;/div&gt;
&lt;ol class=&quot;md-block-ordered-list-item md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;li&gt;نوشتن تست برای امکانات مورد نظر&lt;/li&gt;
&lt;li&gt;اجرا کردن تست ها و مشاهده خطاهایی که دریافت میکنیم&lt;/li&gt;
&lt;li&gt;پیاده سازی ساختار فیچر مورد نظر&lt;/li&gt;
&lt;li&gt;اجرای مجدد تست ها و بررسی خطا های دریافتی&lt;/li&gt;
&lt;li&gt;پیاده سازی لاجیک &lt;/li&gt;
&lt;li&gt;بررسی پاس شدن تست های نوشته شده&lt;/li&gt;
&lt;/ol&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
همونطور
 که میبینید تو این ۶ مرحله به هیچ وجه قبل از اینکه تست ها رو بنویسیم 
درگیر نوشتن خود متد یا امکانات مورد نظرمون نشدیم. اگه این روش رو پیش 
بگیزیم میتونیم مطمئن باشیم بخش عمده ای از کدمون قبل از ورود به محیط 
پروداکشن تست شده و در ادامه با خطاهای کمتری مواجه خواهیم شد. &lt;/div&gt;
&lt;div class=&quot;md-block-unstyled md-block-rtl&quot; dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
حالا که با مفاهیم برنامه نویسی تست محور آشنا شدیم، توی &lt;a class=&quot;md-inline-link&quot; href=&quot;https://virgool.io/@r.a.majd/test-driven-development-part-2-ygwj8tzd6rta&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;قسمت بعد&lt;/a&gt;
 میخوایم تا با استفاده از یک مثال ساده به طور عملی با این مفاهیم برخورد 
داشته باشیم و بهتر این تکنیک رو درک کنیم. پس اگه این مطلب براتون جذاب 
بود پیشنهاد میکنم &lt;a class=&quot;md-inline-link&quot; href=&quot;https://virgool.io/@r.a.majd/test-driven-development-part-2-ygwj8tzd6rta&quot; rel=&quot;noopener noreferrer&quot; target=&quot;_blank&quot;&gt;قسمت دوم&lt;/a&gt; رو هم مطالعه کنید.&lt;/div&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/7188289178397713308/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2020/01/test-driven-development-part-1.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/7188289178397713308'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/7188289178397713308'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2020/01/test-driven-development-part-1.html' title='برنامه نویسی تست محور (TDD) - قسمت اول'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhacyEOZCZRyptUBGPHCU2EFRP_bmfJVvr0eEi7VbklhAN_jhyzfkliZNOqi_pQPD4KVCr2dWZBNBD3VhQBhL_HoSyfFvDO6HFMA41QI4uJhbG43iPDFHp_aTnbhQwWTfxe33vOmg/s72-c/tdd1.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-6610213658963883480</id><published>2017-01-19T15:54:00.000+03:30</published><updated>2017-01-19T16:07:16.012+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="تقویم تاریخ"/><category scheme="http://www.blogger.com/atom/ns#" term="شخصی"/><title type='text'>پلاسکو در آتش سوخت...</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8zIsnOfGj8c17NjC0ztXTC2qdwf1-BLVFMorjGQXfnvOwlDaDO8zfAPxcAgnZ3kzQGgmypK7rC6RJwN5okRcicOfIB68QhipPZEFi1p5ElWZZHbCVuSCYgxC3hJb9ECpnTcr4kg/s1600/plasco.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;391&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8zIsnOfGj8c17NjC0ztXTC2qdwf1-BLVFMorjGQXfnvOwlDaDO8zfAPxcAgnZ3kzQGgmypK7rC6RJwN5okRcicOfIB68QhipPZEFi1p5ElWZZHbCVuSCYgxC3hJb9ECpnTcr4kg/s400/plasco.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
پلاسکو در آتش سوخت و با خودش آتش نشان هایی رو برد که&lt;br /&gt;
شجاعتشون باعث شده ما امروز احساس امنیت و آرامش بکنیم... &lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/6610213658963883480/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2017/01/plasco-on-fire.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/6610213658963883480'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/6610213658963883480'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2017/01/plasco-on-fire.html' title='پلاسکو در آتش سوخت...'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8zIsnOfGj8c17NjC0ztXTC2qdwf1-BLVFMorjGQXfnvOwlDaDO8zfAPxcAgnZ3kzQGgmypK7rC6RJwN5okRcicOfIB68QhipPZEFi1p5ElWZZHbCVuSCYgxC3hJb9ECpnTcr4kg/s72-c/plasco.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-137998432057006815</id><published>2016-11-11T21:30:00.000+03:30</published><updated>2016-11-11T21:30:17.294+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="شخصی"/><category scheme="http://www.blogger.com/atom/ns#" term="موسیقی"/><title type='text'>Dance Me to the End of Love ...</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZalsAH7ohTq9LIg3WqKV4vUlJWy7JU0cAX7gcgY032ec3akVOD6W77sidXG5S9KoEscqWZL1IkLM5M4Z6npwpgSoiiWLg9ZWA0w5XQgmCcrmiTaF-jws8JwBapwXJWwWsuEgDwA/s1600/Leonard-Cohen-pronto-un-nuovo-album-in-autunno.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;267&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZalsAH7ohTq9LIg3WqKV4vUlJWy7JU0cAX7gcgY032ec3akVOD6W77sidXG5S9KoEscqWZL1IkLM5M4Z6npwpgSoiiWLg9ZWA0w5XQgmCcrmiTaF-jws8JwBapwXJWwWsuEgDwA/s400/Leonard-Cohen-pronto-un-nuovo-album-in-autunno.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
RIP Leonard Cohen (1934 - 2016)&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/137998432057006815/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2016/11/dance-me-to-end-of-love.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/137998432057006815'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/137998432057006815'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2016/11/dance-me-to-end-of-love.html' title='Dance Me to the End of Love ...'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZalsAH7ohTq9LIg3WqKV4vUlJWy7JU0cAX7gcgY032ec3akVOD6W77sidXG5S9KoEscqWZL1IkLM5M4Z6npwpgSoiiWLg9ZWA0w5XQgmCcrmiTaF-jws8JwBapwXJWwWsuEgDwA/s72-c/Leonard-Cohen-pronto-un-nuovo-album-in-autunno.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-7776147666744629358</id><published>2016-07-15T19:14:00.000+04:30</published><updated>2016-07-15T19:16:29.898+04:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ssh"/><category scheme="http://www.blogger.com/atom/ns#" term="اینترنت"/><category scheme="http://www.blogger.com/atom/ns#" term="خط فرمان"/><category scheme="http://www.blogger.com/atom/ns#" term="شبکه"/><title type='text'>دسترسی به پورت های روی سرور از طریق SSH بر روی سیستم لوکال</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXbyyT5XnETEEHDbuahrl0xdb25n7AUFRDOXmMgcyUw8UdLYnR5qkxeDmik5M2vh8I_4qWYTO6qJ8ZDPGHN2yYHVx5aM2uYFhcV23WgcWNgrY26szv4Tpl9GUEFVMGfDuWAAE0Hw/s1600/MySQL_SSH.gif&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXbyyT5XnETEEHDbuahrl0xdb25n7AUFRDOXmMgcyUw8UdLYnR5qkxeDmik5M2vh8I_4qWYTO6qJ8ZDPGHN2yYHVx5aM2uYFhcV23WgcWNgrY26szv4Tpl9GUEFVMGfDuWAAE0Hw/s1600/MySQL_SSH.gif&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
گاهی نیاز داریم به صورت مستقیم به پورتی از سرور لینوکسی بر روی سیستم لوکال دسترسی داشته باشیم. مثل وقتی که بخوایم به دیتابیس روی سرور دسترسی داشته باشیم. برای اینکار میتونیم به راحتی با استفاده از SSH پورت مورد نظرمون رو روی کامپیوتر لوکال فوروارد کنیم. برای اینکار از سوئیچ L بصورت زیر استفاده میکنیم.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot; dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;ssh -L port:address:port host
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
که تو دستور بالا port اول پورت مورد نظر ما روی سیستم لوکال بوده و address:port آدرسی بر روی سرور هستش که میخواین بهش از طریق SSH دسترسی داشته باشیم.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/7776147666744629358/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2016/07/local-access-to-remote-port-using-ssh.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/7776147666744629358'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/7776147666744629358'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2016/07/local-access-to-remote-port-using-ssh.html' title='دسترسی به پورت های روی سرور از طریق SSH بر روی سیستم لوکال'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXbyyT5XnETEEHDbuahrl0xdb25n7AUFRDOXmMgcyUw8UdLYnR5qkxeDmik5M2vh8I_4qWYTO6qJ8ZDPGHN2yYHVx5aM2uYFhcV23WgcWNgrY26szv4Tpl9GUEFVMGfDuWAAE0Hw/s72-c/MySQL_SSH.gif" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-4653192289856342949</id><published>2015-12-25T16:57:00.001+03:30</published><updated>2015-12-25T16:59:26.622+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="grep"/><category scheme="http://www.blogger.com/atom/ns#" term="خط فرمان"/><category scheme="http://www.blogger.com/atom/ns#" term="لینوکس"/><title type='text'>نمایش رنگی خروجی grep در bash</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmL5IXkx51pMwNDqXFPZ40TrG9C13vKkmb5pXiPrXZTSRbwfH0ioQm5HZX6D7bO2grGigmsAk9lDdG425ep8oR2lnvW7ZHwzv2hQ8NLzOEHoHofeuBVkc68NCyohysgM-Dtar9LA/s1600/LXF133.grep.mglass-970-80.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmL5IXkx51pMwNDqXFPZ40TrG9C13vKkmb5pXiPrXZTSRbwfH0ioQm5HZX6D7bO2grGigmsAk9lDdG425ep8oR2lnvW7ZHwzv2hQ8NLzOEHoHofeuBVkc68NCyohysgM-Dtar9LA/s320/LXF133.grep.mglass-970-80.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq &quot;&gt;&lt;b&gt;آپدیت:&lt;/b&gt; از دو روش زیر روش اول از grep ورژن 2.21 توصیه نمیشه و اگه از اون استفاده کنید با پیغام هشدار زیر روبرو میشوید.&lt;br /&gt;
&lt;div dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;grep: warning: GREP_OPTIONS is deprecated; please use an alias or script&lt;/div&gt;&lt;/blockquote&gt;&lt;br /&gt;
یکی از سوئیچ هایی که موقع کار با grep خیلی به دردمون میخوره سوئیچ color هستش که مقدار جستجو رو بصورت رنگی نشون میده. ممکنه تو بعضی دیستروها این سوئیچ بطور پیش فرض ست نشده باشه و مجبور باشیم هر دفعه این سوئیچ رو تایپ کنیم.&lt;br /&gt;
برای اینکه این گزینه رو بطور پیش فرض داشته باشیم، میتونیم از یکی از دو روش زیر استفاده کنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: right;&quot;&gt;روش اول:&lt;/h3&gt;&amp;nbsp;برای اینکار کافیه که متغیر GREP_OPTIONS رو ست کنیم و برای اینکه تو هر بار اجرای bash این متغیر ها ست بشن میتونیم اون رو تو فایل .bashrc خودمون ست کنیم.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot; dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;export GREP_OPTIONS=&quot; --color&quot;
&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3 style=&quot;text-align: right;&quot;&gt;روش دوم:&amp;nbsp;&lt;/h3&gt;راه دوم اینه که از alias ها استفاده کنیم. برای این موضوع میتونیم یک alias برای grep بصورت زیر تعریف کنیم و اون رو به فایل .bashrc خودمون اضافه کنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot; dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;alias grep=&#39;grep --color&#39;
&lt;/pre&gt;&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/4653192289856342949/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2015/12/colorize-grep-in-bash.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/4653192289856342949'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/4653192289856342949'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2015/12/colorize-grep-in-bash.html' title='نمایش رنگی خروجی grep در bash'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjmL5IXkx51pMwNDqXFPZ40TrG9C13vKkmb5pXiPrXZTSRbwfH0ioQm5HZX6D7bO2grGigmsAk9lDdG425ep8oR2lnvW7ZHwzv2hQ8NLzOEHoHofeuBVkc68NCyohysgM-Dtar9LA/s72-c/LXF133.grep.mglass-970-80.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-3849590449542706507</id><published>2015-11-15T20:04:00.000+03:30</published><updated>2015-11-15T20:04:29.791+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="جامعه"/><category scheme="http://www.blogger.com/atom/ns#" term="شخصی"/><category scheme="http://www.blogger.com/atom/ns#" term="پاریس"/><title type='text'>اتفاقات اخیر پاریس و مقایسه اون با عراق، سوریه، افغانستان و ...</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIB62m9neUFm9vfERTfvozyvlG2hAOuVIEjlcfgFPMVILVP6mxCMujfYdkbydm2xSxzUzPmTRfcPEQVuDfBittrksvoznMpkkVG1_-MqPnOqQS6SIRD5iBMLtjm-vqKo-hEjhM-w/s1600/paris.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIB62m9neUFm9vfERTfvozyvlG2hAOuVIEjlcfgFPMVILVP6mxCMujfYdkbydm2xSxzUzPmTRfcPEQVuDfBittrksvoznMpkkVG1_-MqPnOqQS6SIRD5iBMLtjm-vqKo-hEjhM-w/s1600/paris.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
اول از هر چیز موضع خودم در رابطه با اتفاقات اخیر پاریس:&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
من فکر میکنم یه حمله تروریستی تو پاریس انجام شده و همونطور که اگه این اتفاق برای ما میوفتاد این موج همدردی هیچ دردی از ما درمون نمیکرد، الان هم زیاد با این جریان موافق نیستم و برای همین هم خودم رو زیاد قاطی این جریانات نمیکنم. پس موضع من: &lt;b&gt;نه مخالف و نه موافق ...&lt;/b&gt;&lt;/blockquote&gt;
&lt;br /&gt;
&lt;b&gt;خوب حالا&amp;nbsp; بریم سر اصل داستان:&lt;/b&gt;&lt;br /&gt;
یه سری هستن که تا یه اتفاقی تو اروپا ( مثل اتفاقات شارلی ابدو و یا اتفاقات اخیر پاریس) میوفته و همدردی جامعه رو میبینن شروع میکنن که آآآی مگه مردم بقیه دنیا آدم نیستن !!! چرا هفته پیش که تو فلان کشور تو خاورمیانه شونصد نفر کشته شدن صداتون در نیومد؟‌ و به مردم هزار تا انگ غرب زدگی میچسبونن. &lt;br /&gt;
&lt;br /&gt;
به نظر من این مقایسه از اساس اشتباه و نمیشه خاورمیانه ای رو که از سر تا پاش ناامنی میباره رو با اروپایی مقایسه کرد که&amp;nbsp; این جور اتفاقات توش یه اتفاق غیر معمول به حساب میاد. توی خاورمیانه اگه هفته ای باشه که توش عملیات تروریستی (استشهادی) رخ نده، باید تعجب کرد و این اتفاقات به یه امر روزمره تبدیل شده. اما تو اروپایی که به کوچکترین حقوق شهروندان توش اهمیت داده میشه و از قبل براش فکر شده نمیشه گفت که عملیات تروریستی یه موضوع عادی هستش و عکس العمل بین‌المللی به اون باید مشابه موارد مشابه تو خاورمیانه باشه. &lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/3849590449542706507/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2015/11/paris-attacks.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/3849590449542706507'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/3849590449542706507'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2015/11/paris-attacks.html' title='اتفاقات اخیر پاریس و مقایسه اون با عراق، سوریه، افغانستان و ...'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIB62m9neUFm9vfERTfvozyvlG2hAOuVIEjlcfgFPMVILVP6mxCMujfYdkbydm2xSxzUzPmTRfcPEQVuDfBittrksvoznMpkkVG1_-MqPnOqQS6SIRD5iBMLtjm-vqKo-hEjhM-w/s72-c/paris.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-4042035591727020445</id><published>2015-11-14T22:50:00.001+03:30</published><updated>2015-11-14T23:15:51.132+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="mongodb"/><category scheme="http://www.blogger.com/atom/ns#" term="NoSQL"/><category scheme="http://www.blogger.com/atom/ns#" term="بانک اطلاعاتی"/><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><category scheme="http://www.blogger.com/atom/ns#" term="مونگو"/><title type='text'>کوئری بر روی آیتم های فیلد از نوع آرایه در mongodb</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxTWaT7O0_pk9GNdrmPpvc6sPXVrXlDFvxQG5s2KDBsE1suRVD-MEo750pWfx4vUA_Vv3y_IJkmU2-X2tv9DEwoYI1Ab0WnR_OqqvFI5l8E4nbfNCtpf9p99lZAJvNva7bKG9Aw/s1600/mongodb_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;175&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxTWaT7O0_pk9GNdrmPpvc6sPXVrXlDFvxQG5s2KDBsE1suRVD-MEo750pWfx4vUA_Vv3y_IJkmU2-X2tv9DEwoYI1Ab0WnR_OqqvFI5l8E4nbfNCtpf9p99lZAJvNva7bKG9Aw/s400/mongodb_logo.png&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
درصورتی که قصد داشته باشیم document هایی از یک collection خاص را براساس شرطی بر روی یکی از فیلد های از نوع آرایه ای آنها پیدا کنیم میتونیم از عبارت $elemMatch بصورت زیر استفاده کنیم: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;مثال اول: &lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
فرض میکنیم collection ما شامل موارد زیر باشد: &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:javascript&quot; dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;{ _id: 1, results: [ 82, 85, 88 ] }
{ _id: 2, results: [ 75, 88, 89 ] }
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
در این صورت برای پیدا کردن document هایی که قیلد result آنها دارای عدد ۸۸ است بصورت زیر عمل میکنیم: &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:javascript&quot; dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;db.collection.find({
    results: { $elemMatch: 88 }
})
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
همچنین میتوان از شرط های پیچیده تری استفاده نمود:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:javascript&quot; dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;db.collection.find({
    results: {
        $elemMatch: { $gte: 80, $lt: 85 }
    }
})
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;مثال دوم (آیتم های آرایه از نوع آبجکت):&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
فرض میکنیم collection ما شامل موارد زیر باشد:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:javascript&quot; dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;{ _id: 1, results: [ { product: &quot;abc&quot;, score: 10 }, { product: &quot;xyz&quot;, score: 5 } ] }
{ _id: 2, results: [ { product: &quot;abc&quot;, score: 8 }, { product: &quot;xyz&quot;, score: 7 } ] }
{ _id: 3, results: [ { product: &quot;abc&quot;, score: 7 }, { product: &quot;xyz&quot;, score: 8 } ] }
&lt;/pre&gt;
&lt;br /&gt;
برای یافتن مواردی که در آنها product ی با مقدار score بزرگتر مساوی 8 باشد بصورت زیر عمل میکنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:javascript&quot; dir=&quot;ltr&quot; style=&quot;text-align: left;&quot;&gt;db.collection.find({
    results: {
        $elemMatch: {
            product: &quot;xyz&quot;,
            score: { $gte: 8 }
        }
    }
})
&lt;/pre&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/4042035591727020445/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2015/11/mongodb-query-on-array-field.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/4042035591727020445'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/4042035591727020445'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2015/11/mongodb-query-on-array-field.html' title='کوئری بر روی آیتم های فیلد از نوع آرایه در mongodb'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxTWaT7O0_pk9GNdrmPpvc6sPXVrXlDFvxQG5s2KDBsE1suRVD-MEo750pWfx4vUA_Vv3y_IJkmU2-X2tv9DEwoYI1Ab0WnR_OqqvFI5l8E4nbfNCtpf9p99lZAJvNva7bKG9Aw/s72-c/mongodb_logo.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-3947299647377768651</id><published>2015-10-09T21:53:00.000+03:30</published><updated>2015-10-18T20:17:24.117+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="اینترنت"/><category scheme="http://www.blogger.com/atom/ns#" term="خط فرمان"/><category scheme="http://www.blogger.com/atom/ns#" term="شبکه"/><title type='text'>اتصال به یک سرور لینوکسی از طریق SSH بدون نیاز به رمز عبور</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlcCoAcqHsNGJRYf7x35evdmE3I57IkHm90Y383tYFc29zZx_MvoUSYmrZJYpDx9cpGnBI5640WEu71LCnYMfR8VAOyev3i3LmIJhQITdQvDkPcTzJ7sTNRSAk6MhfmAa3E2AatA/s1600/ssh-tunnel-diagram-ht.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlcCoAcqHsNGJRYf7x35evdmE3I57IkHm90Y383tYFc29zZx_MvoUSYmrZJYpDx9cpGnBI5640WEu71LCnYMfR8VAOyev3i3LmIJhQITdQvDkPcTzJ7sTNRSAk6MhfmAa3E2AatA/s1600/ssh-tunnel-diagram-ht.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
ممکنه لازم باشه بطور روزمره به یه سرور ssh بزنیم. برای اینکار با دستور زیر میتونیم کلید عمومی خودمون رو به سرور اضافه کنیم تا موقع لاگین دیگه نیازی به رمز عبور نباشه:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ ssh-copy-id user@server.example.com
&lt;/pre&gt;
&lt;br /&gt;
یا اگه مسیر فایل کلید عمومی رو بخوایم تغییر بدیم بصورت زیر عمل میکنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ ssh-copy-id -i ~/.ssh/id_dsa.pub user@server.example.com
&lt;/pre&gt;
&lt;br /&gt;
یا برای ssh به پورتی غیر از پورت پیش فرض:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;$ ssh-copy-id -i /path/key/file.pub &quot;user@server.example.com -p PORT_NUMBER&quot;
&lt;/pre&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
بروز رسانی: برای ماشین هایی که دستور ssh-copy-id رو پشتیبانی نمیکنند میتوان بصورت زیر عمل نمود:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;cat ~/.ssh/id_rsa.pub | ssh user@machine &quot;mkdir ~/.ssh; cat &amp;gt;&amp;gt; ~/.ssh/authorized_keys&quot;
&lt;/pre&gt;
&lt;/blockquote&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/3947299647377768651/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2015/10/ssh-to-remote-server-without-password-prompt.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/3947299647377768651'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/3947299647377768651'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2015/10/ssh-to-remote-server-without-password-prompt.html' title='اتصال به یک سرور لینوکسی از طریق SSH بدون نیاز به رمز عبور'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlcCoAcqHsNGJRYf7x35evdmE3I57IkHm90Y383tYFc29zZx_MvoUSYmrZJYpDx9cpGnBI5640WEu71LCnYMfR8VAOyev3i3LmIJhQITdQvDkPcTzJ7sTNRSAk6MhfmAa3E2AatA/s72-c/ssh-tunnel-diagram-ht.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-6921533400686432926</id><published>2015-01-15T22:48:00.001+03:30</published><updated>2015-01-16T16:49:01.161+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="mongodb"/><category scheme="http://www.blogger.com/atom/ns#" term="NoSQL"/><category scheme="http://www.blogger.com/atom/ns#" term="بانک اطلاعاتی"/><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><category scheme="http://www.blogger.com/atom/ns#" term="مونگو"/><title type='text'>تغییر نام دیتابیس در MongoDB</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1c4WxSHiZNpN3gW-irgiE_31cBtadGUTKVoYJ6VnV30Zsdq-3CmmpFOowFax4CJFnbAOfa-RWliJYsDvrrLC9fb4mnJYdFcaqTz_os4vrNLqjJ6atBNm3VBkCXM4G3DJl9waYOQ/s1600/mongodb_logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1c4WxSHiZNpN3gW-irgiE_31cBtadGUTKVoYJ6VnV30Zsdq-3CmmpFOowFax4CJFnbAOfa-RWliJYsDvrrLC9fb4mnJYdFcaqTz_os4vrNLqjJ6atBNm3VBkCXM4G3DJl9waYOQ/s1600/mongodb_logo.png&quot; height=&quot;172&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;blockquote&gt;
اگه تا بحال راجع به بانک های اطلاعاتی &lt;code&gt;NoSQL&lt;/code&gt; شنیده باشید، حتما اسم &lt;code&gt;MongoDB&lt;/code&gt;  رو هم شنیدید. یک بانک اطلاعاتی &lt;code&gt;Document Based&lt;/code&gt; که اطلاعات رو بصورت داکیومنت هایی به فرمت &lt;code&gt;JSON&lt;/code&gt; ذخیره میکنه.  &lt;/blockquote&gt;
&lt;blockquote&gt;
الان یه مدته که من هم سر و کارم به این بانک اطلاعاتی افتاده و دارم ازش استفاده میکنم. از این به بعد نکاتی رو که در رابطه با &lt;code&gt;MongoDB&lt;/code&gt; بهشون بر میخورم رو هم تو این وبلاگ داکیومنت میکنم تا شاید بعدا به درد خودم یا کس دیگه ای بخوره. &lt;/blockquote&gt;
&lt;br /&gt;
خوب یکی از مواردی که تو کار با &lt;code&gt;MongoDB&lt;/code&gt; ممکنه بهش بر بخوریم تغییر نام یک دیتابیس هستش. از اونجایی که خود &lt;code&gt;MongoDB&lt;/code&gt; (حداقل تا الان) دستوری رو برای این منظور نداره و باید برای اینکار بصورت دیگه ای عمل کنیم. که در ادامه به چند روش انجام این کار اشاره میکنم:&lt;br /&gt;
&lt;br /&gt;
&lt;h2 id=&quot;تغییر-نام-بوسیله-کپی-کردن-بانک-اطلاعاتی&quot; style=&quot;text-align: right;&quot;&gt;
&lt;b&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;تغییر نام بوسیله کپی کردن بانک اطلاعاتی:&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;br /&gt;
یکی از روش هایی که برای تغییرنام میتونیم استفاده کنیم کپی بانک و پاک کردن نسخه قدیمی اون از روی سرور هستش، برای اینکار بصورت زیر عمل میکنیم: &lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;&amp;gt; db.copyDatabase(&#39;old_database&#39;, &#39;new_database&#39;)
&amp;gt; use old_database
&amp;gt; db.dropDatabase()
&lt;/pre&gt;
&lt;br /&gt;
&lt;h2 style=&quot;text-align: right;&quot;&gt;
&lt;span style=&quot;font-weight: normal;&quot;&gt;تغییر نام بوسیله Backup\Restore:&lt;/span&gt;&lt;br /&gt;
&lt;/h2&gt;
&lt;br /&gt;
&lt;code&gt;MongoDB&lt;/code&gt; برای Backup گیری از بانک ها و همچنین برگردوندن Backup ها دو تا دستور &lt;code&gt;mongodump&lt;/code&gt; و &lt;code&gt;mongorestore&lt;/code&gt; رو ارائه داده که میشه از اونها برای backup گیری از دیتابیس و برگردوندن backup با اسم جدید از اونها استفاده کرد. برای این منظور بصورت زیر عمل میکنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;mongodump --db old_database
mongorestore --db new_database /path/to/old_db_backup
&lt;/pre&gt;
&lt;br /&gt;
پس از برگردوندن backup به سرور وصل میشیم و نسخه قدیمی رو با دستور &lt;code&gt;dropDatabase&lt;/code&gt; پاک میکنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;mongo

&amp;gt; use old_database
&amp;gt; db.dropDatabase()
&lt;/pre&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/6921533400686432926/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2015/01/rename-db-in-mongodb.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/6921533400686432926'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/6921533400686432926'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2015/01/rename-db-in-mongodb.html' title='تغییر نام دیتابیس در MongoDB'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1c4WxSHiZNpN3gW-irgiE_31cBtadGUTKVoYJ6VnV30Zsdq-3CmmpFOowFax4CJFnbAOfa-RWliJYsDvrrLC9fb4mnJYdFcaqTz_os4vrNLqjJ6atBNm3VBkCXM4G3DJl9waYOQ/s72-c/mongodb_logo.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-1551442159806975520</id><published>2014-12-13T12:24:00.000+03:30</published><updated>2014-12-13T12:44:57.855+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="vi"/><category scheme="http://www.blogger.com/atom/ns#" term="خط فرمان"/><category scheme="http://www.blogger.com/atom/ns#" term="لینوکس"/><title type='text'>فعال سازی autoindent در ویرایشگر متن vi</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiE3CwFPNT5FsQRXIop1kgRE5p0ZAWSzM3qTeXd6_TjKFf527-3kXt4CvkI_KvLtNeFQDaIH-Yua_NzM9y0JkpGpIc2npQ80-nBze1pWD_MrLfUUi1m6nxbdXqwVwAcJMLA3vfnA/s1600/Beginner-039-s-Vi-Editor-Guide-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiE3CwFPNT5FsQRXIop1kgRE5p0ZAWSzM3qTeXd6_TjKFf527-3kXt4CvkI_KvLtNeFQDaIH-Yua_NzM9y0JkpGpIc2npQ80-nBze1pWD_MrLfUUi1m6nxbdXqwVwAcJMLA3vfnA/s1600/Beginner-039-s-Vi-Editor-Guide-2.png&quot; height=&quot;264&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
برای کسانی که با لینوکس کار میکنن و زیاد با محیط shell سر و کار دارند، vi یکی از ابزاریه که کار کردن با اون یکی از واجبات به حساب میاد. از ویرایش فایل های config گرفته تا کارهای سطح بالاتری مثل diff گرفتن بین دو فایل.این ادیتور امکانات زیادی رو در اختیار کاربر میزاره که کاربر با کانفیگ vi حتی میتونه از اون به عنوان یه IDE حرفه ای استفاده کنه.&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
یکی از امکاناتی که vi در اختیار کاربر میزاره indent گزاری خودکار هستش که معمولا بطور پیش فرض این گزینه غیر فعال هستش.(البته تا اونجایی که من باهاش برخورد داشتم) برای اینکه بتونیم این امکان رو فعال کنیم باید توی فایل .vimrc خودمون این امکان رو فعال کنیم. برای اینکار این خط رو به فایل تنظیمات خودمون اضافه میکنیم :&lt;/div&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;set autoindent
&lt;/pre&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
بعد از انجام این تنظیم vi بطور خودکار خط های جدید رو با indentation خط قبلی ایجاد میکنه که این امکان بخصوص موقع کدنویسی خیلی بکارمون میاد. &lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/1551442159806975520/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2014/12/enable-autoindent-in-vi-editor.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/1551442159806975520'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/1551442159806975520'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2014/12/enable-autoindent-in-vi-editor.html' title='فعال سازی autoindent در ویرایشگر متن vi'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiE3CwFPNT5FsQRXIop1kgRE5p0ZAWSzM3qTeXd6_TjKFf527-3kXt4CvkI_KvLtNeFQDaIH-Yua_NzM9y0JkpGpIc2npQ80-nBze1pWD_MrLfUUi1m6nxbdXqwVwAcJMLA3vfnA/s72-c/Beginner-039-s-Vi-Editor-Guide-2.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-7835006879298552449</id><published>2014-11-14T21:32:00.004+03:30</published><updated>2020-01-19T12:02:19.281+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="tor"/><category scheme="http://www.blogger.com/atom/ns#" term="اوبونتو"/><category scheme="http://www.blogger.com/atom/ns#" term="اینترنت"/><category scheme="http://www.blogger.com/atom/ns#" term="تور"/><category scheme="http://www.blogger.com/atom/ns#" term="لینوکس"/><category scheme="http://www.blogger.com/atom/ns#" term="پروکسی"/><title type='text'>رفع مشکل نصب obfsproxy بر روی ubuntu</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2HMQW3JMiJO7l_6NaI5bRSV9ffW0vm20b5337aCmNGIBSUiTem3SZHPYxxR7ggb-lTZVRfKAuvY3U83lfcfGAKMNsnFHfoase5Ze0DO9qgNhqDX0vxB39XcHtp08W-QWTSSAl4A/s1600/tor_clickfraud-680x400.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;235&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2HMQW3JMiJO7l_6NaI5bRSV9ffW0vm20b5337aCmNGIBSUiTem3SZHPYxxR7ggb-lTZVRfKAuvY3U83lfcfGAKMNsnFHfoase5Ze0DO9qgNhqDX0vxB39XcHtp08W-QWTSSAl4A/s1600/tor_clickfraud-680x400.jpg&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;چند وقت پیش که داشتم tor رو روی اوبونتو نصب میکردم، سراغ پروکسی گیج کننده (obfsproxy) هم رفتم. اما چون به یه خطایی خوردم بیخیالش شدم و با خود tor بدون استفاده از obfsproxy کار میکردم. تا اینکه امروز تنبلی رو کنار گذاشتم و با یه سرچ کوچیک توی اینترنت راه حل رفع مشکل نصب obfsproxy رو توی اوبونتو پیدا کردم.&lt;/blockquote&gt;&lt;br /&gt;
برای اینکار، بعد از نصب tor باید بسته obfsproxy رو هم نصب کنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;sudo apt-get install tor
sudo apt-get install obfsproxy
&lt;/pre&gt;&lt;br /&gt;
حالا که بسته های مورد نیاز خودمون رو نصب کردیم باید تنظیمات tor رو انجام بدیم تا از obfsproxy استفاده کنه. برای اینکار فایل torrc خودمون رو ویرایش می‌کنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;sudo vi /etc/tor/torrc
&lt;/pre&gt;&lt;br /&gt;
تنظیمات زیر رو به انتهای این فایل اضافه میکنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;UseBridges 1
ClientTransportPlugin obfs2 exec /usr/bin/obfsproxy --managed 
ClientTransportPlugin obfs3 exec /usr/bin/obfsproxy --managed
&lt;/pre&gt;&lt;br /&gt;
در اینجا یه نکته ای وجود داره و اونم اینه که ممکنه که obfsproxy تو مسیر دیگه ای نصب شده باشه ( توی راهنماهایی که توی اینترنت وجود داشت معمولا در مسیر /usr/local/bin ) که باید با توجه به مسیر نصب روی سیستم خودتون مسیر های دو خط آخر رو اصلاح کنید.&lt;br /&gt;
&lt;br /&gt;
حالا بعد از انجام تنظیمات بالا نیاز داریم تا یکسری bridge برای استفاده tor داشته باشیم که برای بدست آوردن جدید ترین bridge ها یک ایمیل به آدرس bridges@torproject.org میفرستیم و توی متن ایمیل مون از یکی از دستورات زیر با توجه به نوع bridgeی که لازم داریم، استفاده میکنیم:&lt;br /&gt;
&lt;br /&gt;
جهت دریافت bridge های عادی:&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;get bridges
&lt;/pre&gt;&lt;br /&gt;
جهت دریافت bridge های بر پایه obfs2: &lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;get transport obfs2
&lt;/pre&gt;&lt;br /&gt;
&amp;nbsp;جهت دریافت bridge های بر پایه obfs3:&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;get transport obfs3
&lt;/pre&gt;&lt;br /&gt;
بعد از اینکه ایمیل درخواست خودمون رو ارسال کردیم، به فاصله چند لحظه یک ایمیل دریافت میکنیم که حاوی ۳ تا آدرس bridge از نوع مورد نظر ماست، این آدرس ها رو هم بصورت زیر در ادامه فایل تنظیمات اضافه میکنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;bridge [transport type] IP_ADDRESS:PORT [finger print]
&lt;/pre&gt;&lt;br /&gt;
بطور مثال برای bridge های عادی:&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;bridge 111.111.111.111:1111 21b87f4b3e43cce851344f0e85a24694b27d114b
&lt;/pre&gt;&lt;br /&gt;
و برای bridge های از نوع obfs2:&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;bridge obfs2 111.111.111.111:1111 21b87f4b3e43cce851344f0e85a24694b27d114b
&lt;/pre&gt;&lt;br /&gt;
حالا که تنظیمات خودمون رو انجام دادیم، فایل تنظیمات رو ذخیره میکنیم و سرویس tor رو دوباره راه اندازی میکنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;sudo service tor restart
&lt;/pre&gt;&lt;br /&gt;
بعد از راه اندازی سرویس tor میتونیم با مشاهده انتهای لاگ فایل tor از وصل شدن اون مطلع بشیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;tailf /var/log/tor/log 
&lt;/pre&gt;&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;Nov 14 20:21:24.000 [notice] We now have enough directory information to build circuits.
Nov 14 20:21:24.000 [notice] Bootstrapped 80%: Connecting to the Tor network.
Nov 14 20:21:24.000 [notice] Bootstrapped 90%: Establishing a Tor circuit.
Nov 14 20:21:31.000 [notice] Tor has successfully opened a circuit. Looks like client functionality is working.
Nov 14 20:21:31.000 [notice] Bootstrapped 100%: Done.
&lt;/pre&gt;&lt;br /&gt;
خوب تا اینجا روش معمول راه اندازی bridge ها بر روی tor بود و اگه قرار نباشه از obfsproxy استفاده کنیم تا اینجا کارمون راه افتاده و میتونیم از tor استفاده کنیم.&lt;br /&gt;
&lt;br /&gt;
اما اگه بخوایم از&amp;nbsp; bridge های بر پایه obfsproxy استفاده کنیم موقع اجرای tor با خطای زیر روبرو میشیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;Nov 14 19:56:34.000 [warn] We were supposed to connect to bridge &#39;54.164.6.73:40872&#39; using pluggable transport &#39;obfs3&#39;, but we can&#39;t find a pluggable transport proxy supporting &#39;obfs3&#39;. This can happen if you haven&#39;t provided a ClientTransportPlugin line, or if your pluggable transport proxy stopped running.
&lt;/pre&gt;&lt;br /&gt;
این خطا به دلیل مشکلی پیش میاد که توی اسکریپت apparmor برای tor وجود داره و برای رفع اون باید فایل اسکریپت apparmor برای tor رو ویرایش کنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;sudo vi /etc/apparmor.d/system_tor
&lt;/pre&gt;&lt;br /&gt;
توی این فایل باید مسیر obfsproxy رو بصورت زیر اضافه کنیم:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;/usr/bin/obfsproxy&amp;nbsp; Ux,
&lt;/pre&gt;&lt;br /&gt;
که فایل اسکریپت به صورت زیر تغییر میکنه:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush: bash&quot;&gt;# vim:syntax=apparmor
#include &amp;lt;tunables/global&amp;gt;

profile system_tor {
&amp;nbsp; #include &amp;lt;abstractions/tor&amp;gt;

&amp;nbsp; owner /var/lib/tor/** rwk,
&amp;nbsp; owner /var/log/tor/* w,

&amp;nbsp; /usr/bin/obfsproxy&amp;nbsp; Ux,&amp;nbsp; ## this is the FIX

&amp;nbsp; /{,var/}run/tor/control w,
&amp;nbsp; /{,var/}run/tor/tor.pid w,
&amp;nbsp; /{,var/}run/tor/control.authcookie w,
&amp;nbsp; /{,var/}run/tor/control.authcookie.tmp rw,

&amp;nbsp; # Site-specific additions and overrides. See local/README for details.
&amp;nbsp; #include &amp;lt;local/system_tor&amp;gt;
}
&lt;/pre&gt;&lt;br /&gt;
حالا با راه اندازی مجدد tor خطای قبلی برطرف میشه و به شبکه tor وصل میشیم. &lt;br /&gt;
&lt;br /&gt;
&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/7835006879298552449/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2014/11/tor-obfsproxy-in-ubuntu.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/7835006879298552449'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/7835006879298552449'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2014/11/tor-obfsproxy-in-ubuntu.html' title='رفع مشکل نصب obfsproxy بر روی ubuntu'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2HMQW3JMiJO7l_6NaI5bRSV9ffW0vm20b5337aCmNGIBSUiTem3SZHPYxxR7ggb-lTZVRfKAuvY3U83lfcfGAKMNsnFHfoase5Ze0DO9qgNhqDX0vxB39XcHtp08W-QWTSSAl4A/s72-c/tor_clickfraud-680x400.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-3102590331662187311</id><published>2014-07-29T20:38:00.000+04:30</published><updated>2014-07-29T20:41:30.229+04:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="اوبونتو"/><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><category scheme="http://www.blogger.com/atom/ns#" term="لینوکس"/><title type='text'>فعال کردن syntax highlighting  در vi در ubuntu</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyZSFHaI2ofBiVaMaXDfMXwC_CB8zi8Yr2xKySkj9js4b_eu869yosUF0nReeRKqmzDmaOwS5BwzmL84_OXvBgplesY2oItOcccWNUIrLNouvkqy65ZQ7Uqc6B4JlHxcXdUfG6pA/s1600/Beginner-039-s-Vi-Editor-Guide-2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyZSFHaI2ofBiVaMaXDfMXwC_CB8zi8Yr2xKySkj9js4b_eu869yosUF0nReeRKqmzDmaOwS5BwzmL84_OXvBgplesY2oItOcccWNUIrLNouvkqy65ZQ7Uqc6B4JlHxcXdUfG6pA/s1600/Beginner-039-s-Vi-Editor-Guide-2.png&quot; height=&quot;264&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
توی اوبونتو بطور پیش فرض یک نسخه minimal‌ از ادیتور&amp;nbsp; vi نصبه و این نسخه خیلی از امکانات این ادیتور رو از جمله امکان syntax highlighting، پشتیبانی نمیکنه. حالا اگه میخواین که از این ادیتور با تمامی امکاناتش استفاده کنید باید نسخه کامل اون رو نصل کنید:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;sudo apt-get install vim
&lt;/pre&gt;
&lt;br /&gt;
بعد از نصب کافیه توی ادیتور با دستورات زیر این امکان رو فعال یا غیر فعال کنید:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;:syntax on 

:syntax off
&lt;/pre&gt;
&lt;br /&gt;
اگر هم میخواین که این امکان بصورت پیش فرض فعال باشه کافیه این دستور رو توی فایل .vimrc خودتون قرار بدین:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;brush:bash&quot;&gt;syntax on
&lt;/pre&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/3102590331662187311/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2014/07/ubuntu-enable-syntax-highlighting-in-vi.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/3102590331662187311'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/3102590331662187311'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2014/07/ubuntu-enable-syntax-highlighting-in-vi.html' title='فعال کردن syntax highlighting  در vi در ubuntu'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgyZSFHaI2ofBiVaMaXDfMXwC_CB8zi8Yr2xKySkj9js4b_eu869yosUF0nReeRKqmzDmaOwS5BwzmL84_OXvBgplesY2oItOcccWNUIrLNouvkqy65ZQ7Uqc6B4JlHxcXdUfG6pA/s72-c/Beginner-039-s-Vi-Editor-Guide-2.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-248674381133633456</id><published>2014-07-13T23:03:00.002+04:30</published><updated>2014-07-13T23:03:58.021+04:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="اینترنت"/><category scheme="http://www.blogger.com/atom/ns#" term="هک"/><category scheme="http://www.blogger.com/atom/ns#" term="گوگل"/><title type='text'>فیشینگ اکانت گوگل</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
گوگل عزیز میخواد درخواست من رو مبنی بر پاک کردن اکانت گوگل ام اجرا کنه و میگه اگه از این عمل مطمئن ام بیخیال ایمیل بشم، اما اگه میخوام این درخواست رو کنسل کنم، از طریق لینک مورد نظر اقدام کنم...&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2pxZN_bERMqUQbgGfGpwZeQDsiAk9Iq7Eij0uTC-XaZk1EvTP50bPc8pxxbeQ4rD7qb5VOhg_WV9thYTIiJinc_amGGPvBQI2GzYY7aArLqlM550mrdZVA-xBIIUTf9HaJyEuRQ/s1600/google_phishing.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2pxZN_bERMqUQbgGfGpwZeQDsiAk9Iq7Eij0uTC-XaZk1EvTP50bPc8pxxbeQ4rD7qb5VOhg_WV9thYTIiJinc_amGGPvBQI2GzYY7aArLqlM550mrdZVA-xBIIUTf9HaJyEuRQ/s1600/google_phishing.png&quot; height=&quot;158&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
متاسفانه یا خوشبختانه ماهی(ماحی) مورد نظر این مرتبه تو تور نیوفتاد...&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote class=&quot;tr_bq&quot;&gt;
&lt;b&gt;پ.ن:&lt;/b&gt; اگه میخواین بیشتر در مورد حملات فیشینگ بدونید میتونید به &lt;a href=&quot;http://jadi.net/2014/06/educate-yourself-about-phishing-attacks/&quot; target=&quot;_blank&quot;&gt;این پست&lt;/a&gt; جادی یه نگاه بندازین.&lt;/blockquote&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/248674381133633456/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2014/07/phishing-attack.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/248674381133633456'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/248674381133633456'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2014/07/phishing-attack.html' title='فیشینگ اکانت گوگل'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2pxZN_bERMqUQbgGfGpwZeQDsiAk9Iq7Eij0uTC-XaZk1EvTP50bPc8pxxbeQ4rD7qb5VOhg_WV9thYTIiJinc_amGGPvBQI2GzYY7aArLqlM550mrdZVA-xBIIUTf9HaJyEuRQ/s72-c/google_phishing.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-6097569938587415604</id><published>2014-07-04T04:53:00.002+04:30</published><updated>2014-07-04T04:53:42.642+04:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><category scheme="http://www.blogger.com/atom/ns#" term="توییتر"/><category scheme="http://www.blogger.com/atom/ns#" term="جاوااسکریپت"/><title type='text'>تغییر مسیر پیش فرض ذخیره ماژول های bower</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKmPVR7F2OyYMKk0QMZ5usLOPMZMNjXXBLzJfsDovWT3Zc-LfvEIL9hW3zDEAPpH6UELoi6mI2Ag5agbPalwOsQFZPRQRQj-M9E1WhOjtO8Nc4xT1htHrrAz9Vcdei9x6MK8uykQ/s1600/bower-logo.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKmPVR7F2OyYMKk0QMZ5usLOPMZMNjXXBLzJfsDovWT3Zc-LfvEIL9hW3zDEAPpH6UELoi6mI2Ag5agbPalwOsQFZPRQRQj-M9E1WhOjtO8Nc4xT1htHrrAz9Vcdei9x6MK8uykQ/s1600/bower-logo.png&quot; height=&quot;281&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
چند وقت پیش با &lt;a href=&quot;http://bower.io/&quot; target=&quot;_blank&quot;&gt;bower&lt;/a&gt; آشنا شدم، یه repository برای ماژول های جاوا اسکریپت که توسط توییتر ایجاد شده، ایده خوبیه و برای استفاده تو پروژه های وب خیلی بدرد میخوره و کلی کار آدم رو راه میندازه. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
یکی از امکانات جالب bower اینه که میشه برای پروژه یک فایل کانفیگ به فرمت json به نام bower.json آماده کرد و بعد موقع نصب برنامه روی سرور با اجرای دستور bower install تمامی ماژول های جاوا اسکریپتی که مد نظر داریم رو برامون نصب میکنه. &lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
بطور پیش فرض مسیری که bower ماژول ها رو توش نصب میکنه کنار فایل bower.json و تو یه پوشه به اسم bower_components قرار داره. ممکنه به هر دلیل بخوایم این مسیر پیش فرض رو عوض کنیم و ماژول ها رو تو یه مسیر دیگه نصب کنیم. برای اینکار باید کنار فایل bower.json‌ یه فایل دیگه به نام &lt;b&gt;.bowerrc&lt;/b&gt; ایجاد کنیم و توی اون فایل که باز هم به فرمت json هستش مسیر خودمون رو به شکل زیر  انتخاب کنیم: &lt;/div&gt;
&lt;br /&gt;
&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;pre class=&quot;brush:js&quot;&gt;{
    &quot;directory&quot; : &quot;public/bower_components&quot;
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;br /&gt;
تو کد بالا من مسیر نصب رو به پوشه public/bower_components تغییر دادم. &lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/6097569938587415604/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2014/07/change-bower-modules-path.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/6097569938587415604'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/6097569938587415604'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2014/07/change-bower-modules-path.html' title='تغییر مسیر پیش فرض ذخیره ماژول های bower'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKmPVR7F2OyYMKk0QMZ5usLOPMZMNjXXBLzJfsDovWT3Zc-LfvEIL9hW3zDEAPpH6UELoi6mI2Ag5agbPalwOsQFZPRQRQj-M9E1WhOjtO8Nc4xT1htHrrAz9Vcdei9x6MK8uykQ/s72-c/bower-logo.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-2295450451399877553</id><published>2013-12-01T13:03:00.000+03:30</published><updated>2013-12-01T13:03:25.311+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="برنامه نویسی"/><category scheme="http://www.blogger.com/atom/ns#" term="جالب انگیز"/><category scheme="http://www.blogger.com/atom/ns#" term="نرم افزار"/><title type='text'>اولین باگ کامپیوتری</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEialCePTuWAX4K1f84cqvVjiNKdWnXxrkYpLOw4ycvchC0K7I9AzsXzylLhBIFFHvIU8m1agwrF-hO74n1fNV1y1tMQXmMC7lcxkQgcxWDftnJ7KE8CMFEXtC6ZMtEfQuKlPdtozg/s1600/computer_bug.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEialCePTuWAX4K1f84cqvVjiNKdWnXxrkYpLOw4ycvchC0K7I9AzsXzylLhBIFFHvIU8m1agwrF-hO74n1fNV1y1tMQXmMC7lcxkQgcxWDftnJ7KE8CMFEXtC6ZMtEfQuKlPdtozg/s1600/computer_bug.jpg&quot; height=&quot;315&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
این تصویر مربوط به اولین باگ کامپیوتریه که در سال 1947 توی کامپیوتر Mark II که در دانشگاه هاروارد در حال تست بود پیدا شده. این باگ در حقیقت یک حشره بود که بین یکی از رله های این کامپیوتر گیر کرده بوده. اپراتور های این کامپیوتر این حشره رو به گزارششون چسبوندن و اون رو به عنوان اولین باگ کامپیوتری ریپورت کردن. این صفحه گزارش هنوز وجود داره و در حال حاضر توی موزه نگهداری میشه ...&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
منبع: &lt;a href=&quot;https://en.wikipedia.org/wiki/File:H96566k.jpg&quot; target=&quot;_blank&quot;&gt;ویکی پدیا&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/2295450451399877553/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2013/12/first-computer-bug.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/2295450451399877553'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/2295450451399877553'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2013/12/first-computer-bug.html' title='اولین باگ کامپیوتری'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEialCePTuWAX4K1f84cqvVjiNKdWnXxrkYpLOw4ycvchC0K7I9AzsXzylLhBIFFHvIU8m1agwrF-hO74n1fNV1y1tMQXmMC7lcxkQgcxWDftnJ7KE8CMFEXtC6ZMtEfQuKlPdtozg/s72-c/computer_bug.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-6303029979601358499</id><published>2013-11-24T11:58:00.002+03:30</published><updated>2013-11-24T11:58:19.505+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="ایران"/><category scheme="http://www.blogger.com/atom/ns#" term="سیاست"/><category scheme="http://www.blogger.com/atom/ns#" term="شخصی"/><title type='text'>خسته نباشی مرد</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ1UWGjM6iMp11PbCBL-RWVQ1O2bm0NNzeAtYKmaKDeRjF-K1S_erM8jxtvyR7KcJyqP2ue1E6r6w1ebvG8w66rt-GOZq00lQSp10pLnINxQmIlhhTsms00gQWJna1IhuzHi5C3Q/s1600/BZzzE-RCcAAXyXQ.jpg+large.jpg&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ1UWGjM6iMp11PbCBL-RWVQ1O2bm0NNzeAtYKmaKDeRjF-K1S_erM8jxtvyR7KcJyqP2ue1E6r6w1ebvG8w66rt-GOZq00lQSp10pLnINxQmIlhhTsms00gQWJna1IhuzHi5C3Q/s1600/BZzzE-RCcAAXyXQ.jpg+large.jpg&quot; height=&quot;312&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
بالاخره تلاش های این چند وقته نتیجه داد و مذاکرات با موفقیت همراه شد، البته هنوز اول راهیم ...&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
به امید ادامه پیدا کردن این روند آشتی با جهان ...&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;a href=&quot;https://twitter.com/JZarif&quot; target=&quot;_blank&quot;&gt;@JZarif &lt;/a&gt;ممنون بابت زحمات این چند وقته، خسته نباشید ...&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/6303029979601358499/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2013/11/Geneva-negotiations.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/6303029979601358499'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/6303029979601358499'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2013/11/Geneva-negotiations.html' title='خسته نباشی مرد'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQ1UWGjM6iMp11PbCBL-RWVQ1O2bm0NNzeAtYKmaKDeRjF-K1S_erM8jxtvyR7KcJyqP2ue1E6r6w1ebvG8w66rt-GOZq00lQSp10pLnINxQmIlhhTsms00gQWJna1IhuzHi5C3Q/s72-c/BZzzE-RCcAAXyXQ.jpg+large.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-4121691835537915923</id><published>2013-11-06T09:57:00.000+03:30</published><updated>2013-11-06T09:57:54.114+03:30</updated><title type='text'>تست Syntax Highlighting</title><content type='html'>&lt;pre class=&quot;brush:js&quot;&gt;console.log(&quot;Hello World!!!&quot;);
&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/4121691835537915923/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2013/11/syntax-highlighting.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/4121691835537915923'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/4121691835537915923'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2013/11/syntax-highlighting.html' title='تست Syntax Highlighting'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6325922.post-2007080494442325826</id><published>2013-09-29T14:32:00.000+03:30</published><updated>2013-09-29T14:32:09.579+03:30</updated><category scheme="http://www.blogger.com/atom/ns#" term="اینترنت"/><title type='text'>وب سایت شرکت پارس جنوبی</title><content type='html'>&lt;div dir=&quot;rtl&quot; style=&quot;text-align: right;&quot; trbidi=&quot;on&quot;&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
چیزی که در زیر مشاهده میکنید صفحه نخست سایت &lt;a href=&quot;http://spgc.ir/&quot; target=&quot;_blank&quot;&gt;شرکت معظم پارس جنوبی&lt;/a&gt;ه:&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiafNIH6c36dJJMAkQRnoqGgyhH2NX8aEmGFq_i1bBfIixMd_j5z34Cquyre-R-ZPehsOgJgCLAzwZLbo5kJnykfqQGM0nCTivVolnhjCGig0q3nQp0qLWETh7uM80rvsKT6G-Zvw/s1600/south_pars.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiafNIH6c36dJJMAkQRnoqGgyhH2NX8aEmGFq_i1bBfIixMd_j5z34Cquyre-R-ZPehsOgJgCLAzwZLbo5kJnykfqQGM0nCTivVolnhjCGig0q3nQp0qLWETh7uM80rvsKT6G-Zvw/s1600/south_pars.PNG&quot; height=&quot;295&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
دو تا نکته:&amp;nbsp;&lt;/div&gt;
&lt;ul style=&quot;text-align: justify;&quot;&gt;
&lt;li&gt;نکته اول اینکه چرا باید اطلاعات debug بصورت remote قابل مشاهده باشه، اونم تو سیستم عملیاتی و نه سیستم تست.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;از اون مهمتر اینکه اصلا چرا فکری برای مشکل ساده ای مثل از دسترس خارج شدن دیتابیس نشده.&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
---&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
الان که دوباره چک کردم انگار دوستان متوجه مشکل شدن و یه Custom Error Page به سیستم اضافه کردن اونهم بهمراه غلط املایی:&amp;nbsp;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4_Vfa1QomMMISRLGZR_xofM20I2mY5dMGBlApo3s5Ai3lbjS9eo44LXX-FsZ1sZIEXUj_tQNTnWGxEZipQxnaP4voE_1ofqt7RAM4DirpbCujxd4UGG1-jxM3Ea7EAaUxyjkegg/s1600/south_pars2.PNG&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4_Vfa1QomMMISRLGZR_xofM20I2mY5dMGBlApo3s5Ai3lbjS9eo44LXX-FsZ1sZIEXUj_tQNTnWGxEZipQxnaP4voE_1ofqt7RAM4DirpbCujxd4UGG1-jxM3Ea7EAaUxyjkegg/s1600/south_pars2.PNG&quot; height=&quot;206&quot; width=&quot;400&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: justify;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='https://blog.deadman.ir/feeds/2007080494442325826/comments/default' title='نظرات پیام'/><link rel='replies' type='text/html' href='https://blog.deadman.ir/2013/09/south-pars-website.html#comment-form' title='0 نظر'/><link rel='edit' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/2007080494442325826'/><link rel='self' type='application/atom+xml' href='https://www.blogger.com/feeds/6325922/posts/default/2007080494442325826'/><link rel='alternate' type='text/html' href='https://blog.deadman.ir/2013/09/south-pars-website.html' title='وب سایت شرکت پارس جنوبی'/><author><name>Reza Alizadeh Majd</name><uri>http://www.blogger.com/profile/11175870143728061010</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiafNIH6c36dJJMAkQRnoqGgyhH2NX8aEmGFq_i1bBfIixMd_j5z34Cquyre-R-ZPehsOgJgCLAzwZLbo5kJnykfqQGM0nCTivVolnhjCGig0q3nQp0qLWETh7uM80rvsKT6G-Zvw/s72-c/south_pars.PNG" height="72" width="72"/><thr:total>0</thr:total></entry></feed>