Friday, March 30, 2007

Vim

شاید شما بر روی کامپیوتر خود یکی از این ویرایشگرهایی که با آن همه جور فایل متنی را می توانید edit کنید دارید. Notepad++، JEdit، Ultra Edit، Crimson Editor و ... شاید بتوان صد تای دیگر از این جور ویرایشگرها نام برد. این را هم بگویم که نمی دانم اگر چنین چیزی بر روی کامپیوترتان ندارید چطور زندگی می کنید!

از بین همه ویرایشگر های موجود، من شخصا علاقه خاصی به vim دارم. vim یکی از قدرتمند ترین و متداول ترین ویرایشگرهای موجود است، اگر با Linux کار کرده باشید حتما با آن مواجه شده اید. vim ویژگی های بسیار خوب و جالبی دارد، اول اینکه می توان با آن نزدیک 500 نوع فایل متنی را ویرایش کرد که تقریبا شامل همه زبان های برنامه نویسی و بقیه فایل های متنی می شود. دوم اینکه vim تقریبا تحت هر پلتفرمی که فکرش را بکنید کار می کند، از ویندوز و لینوکس و مک گرفته تا داس و آمیگا! این برای کسانی که با پلت فرم های مختلف کار می کنند ویژگی مثبتی است. سوم اینکه vim خیلی light weight هست و خیلی سریع load می شود. چهارم اینکه vim اپن سورس است(ویژگی که حداقل برای من خیلی مهم است).

آخرین نسخه این ویرایشگر را می توانید از اینجا دانلود کنید. اگر با ویندوز کار می کنید توصیه می کنم installer آن را دانلود کنید(self-installing executable) ولی اگر با لینوکس کار می کنید به احتمال زیاد این ویرایشگر قبلا بر روی سیستم عامل شما نصب شده.

در حالت پیش فرض vim یک ویرایشگر حرفه ای است و برای شروع به کار نیاز به کمی آموزش دارد ولی خوشبختانه آنقدر انعطاف پذیر هست که بتوان آن را همان طور که دوست داریم پیکر بندی کنیم. برای این کار اگر در محیط ویندوز هستید به پوشه نصب vim بروید(معمولا program files\vim) و فایل _vimrc را باز کنید(در لینوکس معمولا این فایل با نام .vimrc و در پوشه کاربر قرار دارد). سپس خطوط زیر را به انتهای این فایل اضافه کنید:

color blue

set nobackup

set guifont=Courier_New:h12

set encoding=utf-8

set insertmode

set spell

set nowrap

set guioptions+=r

set guioptions+=b

خط color blue رنگ های پیش زمینه و پس زمینه را به گونه ای که در colorschema ای با نام blue تعریف شده تغییر می دهد. به جای blue می توانید اسم هر کدام از فایل هایی را که در پوشه colors واقع در پوشه نصب vim موجود است استفاده کنید. توصیه می کنم colorschema را تغییر دهید تا یکی را که به نظرتان مناسب است پیدا کنید.

وقتی فایلی را تغییر می دهید، بصورت پیش فرض vim یک نسخه از فایل قدیمی را به عنوان backup نگه می دارد. این نسخه بطور پیش فرض در کنار همان فایل جدید نگه داشته می شود. این کار باعث شلوغ شدن دیسک می شود. خط set nobackup باعث می شود که دیگر backup نگه داشته نشود. اگر به جای این خط از set backupdir=c:\\backups استفاده کنید vip تمام backup ها را در پوشه ای که مشخص کرده اید ذخیره می کند.

همان طور که مشخص است set guifont=Courier_New:h12 فونت و اندازه متن را در ویرایشگر مشخص می کند.

خط set insertmode باعث می شود vim در مد insert شروع شود. vim از مدهای مختلفی پشتیبانی می کند که برای مقاصد مختلفی استفاده می شود ولی مد insert خیلی شبیه حالت عادی ویرایشگرهای دیگر است.

خط set spell، spell checking را در vim فعال می کند.

خطوط set guioptions+=r و set guioptions+=b باعث می شود vim در سمت راست و پایین scrollbar هایی را نشان دهد.

اگر در محیط ویندوز از installer استفاده کرده باشد، یک گزینه Edit with Vim به منوی Windows Explorer اضافه شده است. با استفاده از این گزینه بر روی هر فایلی که کلیک راست کنید می توانید آنرا توسط vim باز کنید.

Monday, March 05, 2007

حریم خصوصی

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

سایتی مثل یاهو یا گوکل اجزای مختلفی از جمله موتور جستجو، ایمیل، گراف های دوستی(یاهو 360 و orkut) ، صفحه های شخصی، مسنجر و ... دارند. هر کدام از این اجزا برای پی بردن به اطلاعات زیادی از زندگی شخصی یک نفر کافی است. برای اینکه موضوع روشن شود، سعی می کنم روشهایی را که این سایت ها برای به دست آوردن اطلاعات شخصی افراد می توانند مورد استفاده قرار دهند را نام ببرم:

نام و نام خانوادگی شما چیست ؟

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

کجا زندگی می کنید، کجا کار می کنید؟

اینکه از کجا به سرور لاگین کرده اید به راحتی از روی آدرس IP شما قابل تشخیص است. اگر باور نمی کنید می توانید صفحه شخصی یا وبلاگ خود را به لیست Google Analytic اضافه کنید تا ببینید Google Analytic چه اطلاعات دقیقی را در مورد محل بازدید کنندگان از سایت شما در اختیارتان قرار میدهد. گرچه این اطلاعات ممکن است صد در صد درست نباشد اما تا حدود زیادی می توان به آنها اطمینان کرد.

دنبال چه چیزهایی می گردید؟

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

دوستان شما چه کسانی هستند؟

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

به چه چیزهایی علاقه دارید؟

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

دیگه چه خبر از زندگی؟

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

رمز عبورتان چیست ؟

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

در ماه اخیر تعداد سایت هایی که پسورد ایمیل یاهو ،گوگل یا Hotmail را به بهانه دسترسی به Contact List شما می گیرند بسیار زیاد شده. جالب اینکه در بعضی از این سایت ها (مثل tagged.com) اگر پسورد ایمیل خود را درست وارد نکنید اجازه ثبت نام به شما را نمی دهد.

کلام آخر:

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

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

Tuesday, January 23, 2007

Ruby 4

قسمت اول

قسمت دوم

قسمت سوم

Meta Programming

یکی از روش هایی که در Ruby زیاد استفاده می شود meta programming است. meta programming را بطور ساده می توان نوشتن کدی که کد دیگری را تولید می کند بیان کرد. meta programming در زبان های دیگر مانند جاوا و زبان های پلت فرم دات نت هم وجود دارد. در دات نت یک روش متداول برای این کار استفاده از Attribute ها است. یک مثال متداول استفاده از Attribute های WebMethod و WebService برای ساختن سرویس های وب هست. در جاوا تا قبل از JDK 1.5 روش متداول استفاده از XML برای این کار بود (برای مثال Axis برای تولید Stub های وب سرویس ها از XML استفاده می کرد) ولی بعد از معرفی Annotation ها(مکانیزمی شبیه Attribute ها در دات نت) در JDK 1.5 روش جایگزینی برای استفاده از XML مطرح شد. در هر حال ایده کلی برای meta programming در زبان های کامپایلری این است برنامه نویس اطلاعات اضافی را وارد کند(با استفاده از XML، Annotation، Attributes یا هر روش دیگری). سپس یک ابزار(مانند APT در جاوا) با بررسی این اطلاعات اضافی کدی را تولید کند که بتوان آنرا با استفاده از کامپایلر کامپایل کرد. روش های دیگری که برای meta programming در جاوا استفاده می شود تغیر در بایت کد کلاس ها هنگام load کردن کلاس ها، استفاده از dynamic proxy ها و تولید کلاس ها در زمان اجرا است که عمدتا روش های پیچیده ای هستند.

meta programming در Ruby بسیار ساده تر و متداول تر است. برای مثال مسئله دسترسی به فیلدهای یک شیئ را در نظر بگیرید. در جاوا راه حل متداول نوشتن متد های getter و setter و در C# استفاده از Property ها است. بطور معمول این مکانیزم ها یک کار را تکرار می کنند(getter ها مقدار فیلد را بر می گردانند و setter ها مقدار فیلد را تغییر می دهند). Ruby برای این کار راه حل جالبی دارد، در Ruby با استفاده از متدهای attr_reader و attr_writer می توان getter و setter و با استفاده از attr_accessor می توان هر دوی آنها را درست کرد. جالب این که این متد ها، متد های خاصی نیستند و تنها کاری که می کنند این است که رشته ای را درست کرده و برای اجرا به مفسر Ruby می دهند.

class FieldTest

attr_reader :r

attr_writer :w

attr_accessor :rw

def to_s

"@r, @w, @rw"

end

end

ft = FieldTest.new

ft.w = 111

ft.rw = "hello"

puts ft.r

یک راه حل ساده برای meta programming در Ruby استفاده از توابع eval است. این توابع معمولا یک رشته را به عنوان ورودی می گیرند و آن را اجرا می کند. فرض کنید می خواهیم کلاسی داشته باشیم که متد هایی با نام اعداد 1 تا 5 دارند و مقدار این اعداد را بر می گردانند، یک راه حل این است که 5 متد مختلف بنویسیم که مقادیر مورد نظر را بر می گردانند ولی یک راه حل بهتر در ادامه آورده شده:

class Numbers

nums = {'one' => 1, 'two' => 2, 'three' => 3, 'four' => 4, 'five' => 5}

nums.each do |k, v|

module_eval "def #{k} \n #{v} \nend"

end

end

# Test class Numbers

n = Numbers.new

puts n.one # prints 1

puts n.two # prints 2

puts n.three # prints 3

puts n.four # prints 4

puts n.five # prints 5

متد module_eval رشته داده شده را به مفسر Ruby می فرستد تا آنرا اجرا کند. یک ویژگی بسیار مطلوب meta programming این است که حجم کد نوشته شده را بسیار کاهش می دهد(تصور کنید کلاس Numbers که در اینجا تنها در 4 خط نوشته شده در حالت عادی چه حجم زیادی می داشت) ولی ویژگی های مهم تری هم دارد که در ادامه به آن پرداخته ام.

Aspect Oriented Programming:

AOP یکی از روش های برنامه نویسی است که این روز ها خیلی در مورد آن صحبت می شود. AOP قابلیت های بسیاری به زبان های شیئ گرا اضافه می کند. بسیاری AOP را بعد از روش های ساخت یافته و شیئ گرا، بزرگترین تحول در دنیای برنامه نویسی دانسته اند. نکته جالب توجه این است که وقتی با Ruby کار می کنید، نیاز چندانی به AOP پیدا نمی کنید. عمده کارهایی که در AOP با آن مواجه هستید، اضافه کردن یک متد به یک کلاس، جایگزین کردن یک متد با یک متد جدید و اجرای یک کد قبل یا بعد از یک متد است. در Ruby به راحتی می توانید تمام این کارها را انجام دهید. مثلا فرض کنید بخواهید قبل از اینکه متد sort از کلاس Array فراخوانی شود، رشته ای را چاپ کنیم تا از فرا خوانی این متد باخبر شویم. کافی است کلاس Array را باز کنیم، متد sort را به old_sort تغییر نام دهیم و متد sort جدیدی را تعریف کنیم، در متد جدید کافی است رشته مورد نظر را چاپ کنیم و بعد متد قدیمی را فراخوانی کنیم:

class Array

alias_method :old_sort, :sort

def sort

puts 'Array.sort called !'

old_sort

end

end

#Test new sort

a = [3, 2, 4, 1, 4]

puts a.sort

# Output:

# Array.sort called !

# 1 2 3 4 4

البته یکی از ویژگی های زبانهایی که از AOP پشتیبانی می کنند(مانند AspectJ) پشتیبانی از wildcard ها است که چنین چیزی بطور استاندارد در Ruby پشتیبانی نمی شود.

Database:

یکی از مسائل مهمی که هر زبان برنامه نویسی باید برای حل آن فکری بکند کار کردن با پایگاه داده در آن زبان است. زبان های مختلف راهکار های متعددی برای این مسئله ارائه داده اند، در جاوا استاندارد ساده JDBC شاید اولین تلاش در این زمینه بود. بعد از آن ارائه EJB ها (با همه سر و صدایش) و سپس راه حل های مختلف بر پایه Object Relational Mapping مثل Hibernate، iBatis و Apache OJB نشان از تلاش های گسترده در این زمینه دارد. در دنیای دات نت هم کپی های این ORM ها مثل NHibernate و iBatis.NET، تکنولوژی هایی مثل ADO.NET و در نهایت ابتکار جدید ماکروسافت به نام LINQ وجود دارد. نکته مشترکی که در تمام این راه حل ها وجود دارد static بودن زبانی است که راه کار به وسیله آن پیاده سازی شده.

اما در پایگاه داده هم Ruby راه حل ساده خود را دارد. راه حل Ruby برای این کار ActiveRecord نام دارد. فرض کنید که در پایگاه داده خود جدولی به نام Students دارید که دو فیلد name و id دارد. قطعه کد زیر یک رکورد به جدول Students اضافه می کند:

ActiveRecord::Base.establish_connection(:adapter => "mysql",

:host => "127.0.0.1",

:username => "root",

:password => "",

:database => "Uni")

class Student <

ActiveRecord::Base

# Fields are fetched from database automatically

end

stu = Student.new

stu.name = 'mohsen'

stu.id = 12345

stu.save

هنگامی که کلاسی از ActiveRecord::Base ارث می برد، این کلاس بطور اتوماتیک فیلدهای پایگاه داده را به کلاس مورد نظر اضافه می کند، نکته جالب این است که ActiveRecord برای پیدا کردن فیلدها به دنبال جدولی هم نام با کلاس(ولی بصورت جمع) می گردد. این راه حل در Ruby زیاد استفاده می شود و باعث ساده شدن کار می شود. البته اگر جداول ما نام دیگری هم داشته باشند می توان ActiveRecord را برای استفاده از آن بکار برد ولی در این حالت باید اسم جدول برای آن مشخص شود.

همچنین ActiveRecord قادر است روابط یک به چند و چند به چند بین جداول را به کلاس های برنامه map کند، ولی در اینجا قصد پرداختن به جزئیات این مسئله را ندارم.

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

Web:

شاید آن چیزی که باعث متداول شدن Ruby شد پلت فرم وبی بود که بر روی این زبان ایجاد شده بود. این پلت فرم Ruby on Rails نام دارد و تغیرات زیادی را در طرز تفکر توسعه دهندگان در دنیای وب ایجاد کرده. پرداختن به Ruby on Rails خود بحث مفصلی است که در این کوچک نوشته نمی گنجد!

معایب Ruby:

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

نکته اول اینکه Ruby یک زبان اسکریپتی است و مسلما به مراتب کند تر از زبان های کامپایلری است، ولی این نکته را هم بگویم که سرعت اجرا یکی از فاکتورهای یک زبان است و بستگی زیادی به پیاده سازی آن دارد. امروزه با توجه به کاهش قیمت سخت افزار و افزایش سرعت کامپیوترها از اهمیت سرعت اجرا به شدت کاسته شده و فاکتورهای دیگری در زبان های برنامه نویسی اهمیت پیدا کرده اند(البته زبان های اسکریپتی را دست کم نگیرید و فراموش نکنید که ویکیپدیا یکی از بزرگترین سایت های اینترنت بر روی PHP کار می کند)

نکته دوم اینکه استفاده از یک زبان اسکریپتی به معنی این است که سورس کد برنامه شما در دسترس همه قرار دارد که در بسیاری از موارد قابل قبول نیست(البته می توان از تکنیک هایی مثل Obfuscation هم استفاده کرد ولی در هر حال این کار هم مشکلات خاص خود را دارد)

نکته سوم اینکه هنگامی که با یک زبان کامپایلری کار می کنید بسیاری از مشکلات احتمالی در زمان کامپایل چک می شود و در زمان اجرا با مشکلات کمتری روبرو هستید. برای پی بردن به بسیاری از مشکلات در Ruby باید برنامه خود را اجرا کنید. از این رو برنامه های نوشته شده به زبان Ruby وابستگی زیادی به Unit Testing و Code Coverage دارند.

نکته چهارم اینکه Ruby هنوز به اندازه لازم به تکامل نرسیده. هنوز انجام یک پروژه بزرگ با جاوا ریسک کمتری را تحمیل می کند. هنوز ابزار های توسعه در Ruby در اوایل کار خود قرار دارند و راه درازی تا رسیدن به آنجایی که امروزه ابزارهای زبان هایی مثل جاوا و دات نت قرار دارند باقی مانده.

کلام آخر:

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

مراجع:

[1] Beyond Java, By Bruce A. Tate, O'Reilly, September 2005, ISBN: 0-596-10094-9

[2] Ruby Cookbook, By Lucas Carlson, Leonard Richardson, O'Reilly, July 2006, Print ISBN-13: 978-0-59-652369-5

[3] Programming Ruby, The Pragmatic Programmers’ Guide, Second Edition, Dave Thomas