گنجه
۰۹ ۲۴م, ۱۳۸۷
از وقتی با Greasemonkey آشنا شدهام توقعم از تار1 خیلی بالا رفته.
با این افزونهٔ Firefox میشه در طرف مخدوم2، به هر صفحهای کدهای JavaScript دلخواه رو اضافه کرد. علاوه بر کلی دستنوشتهٔ3 آماده که توی http://userscripts.org براش وجود داره، خودمون هم میتونیم به راحتی براش دستنوشته بنویسیم. حالا اگر قدرت JavaScript رو بیاری تو ذهنت میبینی که چه کارها میشه به کمک این میمون چرب (!) کرد.
برای شروع ماجراجویی، کمی از http://diveintogreasemonkey.org رو خوندم. نقطهٔ شروع بسیار خوبی بود.
یک دستنوشته به نام فارسنده یا Persianizer که به شیوهٔ بِکَن-بچسبون4 ساختهام، همهٔ رقمهای انگلیسی و «ي» و «ك»های عربی توی صفحهٔ بارگذاری شده رو به معادل فارسیشون تبدیل میکنه. بس که اون صفحههای فارسی پر از «ي» حالم رو بد میکنه! فقط موقع استفاده حواست باشه پایگاههایی که قراره فارسنده روشون کار بکنه رو خوب انتخاب کنی؛ پیشفرضهاش خوب نیستند.
البته یکی از شرایط من (و خیلیهای دیگر) برای استفاده از یک فنآوری، انحصاری نبودنش هست که خوشبختانه افزونههایی سازگار با Greasemonkey برای مرورگرهای مهم دیگه (از جمله Konqueror) هم وجود داره.
نکتهٔ پایانی این که اگر کاربر Greasemonkey باشی، افزونهٔ Greasefire هم احتمالاً برات جالب هست.
این هم فهرست دستنوشتههای محبوب من:
http://userscripts.org/users/73214/favorites
۰۹ ۳م, ۱۳۸۷
اگر برنامهنویس C++ باشی، حتماً تا حالا مورد آزار و اذیت پیغامهای خطای سرسامآور همگردان0 در مورد STL قرار گرفتهای. مثلاً این:
testmm2.cpp:31: error: no matching function for call to ‘std::multimap<int*, int, std::less<int*>, std::allocator<std::pair<int* const, int> > >::insert(int)’ /usr/include/c++/4.3/bits/stl_multimap.h:407: note: candidates are: typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const_Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(const std::pair<const _Key, _Tp>&) [with _Key = int*, _Tp = int, _Compare = std::less<int*>, _Alloc = std::allocator<std::pair<int* const, int> >] /usr/include/c++/4.3/bits/stl_multimap.h:431: note: typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator std::multimap<_Key, _Tp, _Compare, _Alloc>::insert(typename std::_Rb_tree<_Key, std::pair<const _Key, _Tp>, std::_Select1st<std::pair<const _Key, _Tp> >, _Compare, typename _Alloc::rebind<std::pair<const _Key, _Tp> >::other>::iterator, const std::pair<const _Key, _Tp>&) [with _Key = int*, _Tp = int, _Compare = std::less<int*>, _Alloc = std::allocator<std::pair<int* const, int> >]
حالا این یکی بود. وقتی ده-پونزده تا از اینها یکجا رخ میده، خیلی افتضاح میشه.
مدتها با این مشکل کنار اومده بودم و دردش رو تحمل میکردم. اما اخیراً یک راه نجات یافتم: ابزاری به نام STLFilt. یک نرمافزار آزاد هست که خروجی همگردان C++ رو میگیره و اون پیغامهای وحشتناک رو مهربون میکنه. مثلاً پیغام بالا رو تبدیل میکنه به این:
testmm2.cpp:31: error: No match for ‘multimap<int *, int>::insert(int)’
stl_multimap.h:407: candidates are: map<int *, int>::iter multimap<int *, int>
::insert(const pair<const int *, int> &)
stl_multimap.h:431: map<
int *, int
>::iter multimap<
int *, int
>::insert(map<int *, int>::iter, const pair<const int *, int> &)آخش! حالا میشه خوندش!
برای استفاده از STLFilt اول باید بستهٔ مربوط به همگردانت رو بگیری. مثلاً gstlfilt.zip برای G++. توش کلی پرونده هست که همه رو بیخیال میشی به جز gSTLFilt.pl که اصل کار رو انجام میده. از stdin میخونه و توی stdout مینویسه. کاری که من کردم این بود1:
sudo su F=/usr/local/bin/stlfilt.pl echo '#!/usr/bin/perl' >$F cat gSTLFilt.pl >>$F chmod +x $F
و برای استفاده:
make 2>&1 | stlfilt.pl
برای این که هر بار نخوام stderr دستور ساخت2 (مثلاً make) رو به stdoutش redirect3 کنم، دستنوشتهٔ4 /usr/local/bin/stlfilt رو با این محتوا ساختم:
#!/bin/sh "$@" 2>&1 | stlfilt.pl
و chmod +x هم یادم نره. ![]()
حالا اینجوری استفاده میشه:
stlfilt makeبا دستنوشتهها زندگی زیباتره!
ویرایش: امید آن میرود که با معرفی «مفهوم»5ها در C++0x (به زودی!) کل مشکل از بیخ حل بشه و دیگه نیازی به ابزار اضافی نباشه.