Tuesday, December 23, 2008

Ubuntu: Reset Gnome Panels

I've been customizing my gnome panels, and I happened to mess them up pretty bad. However, I found an awesome way to reset the gnome panels back to the default here.

gconftool --recursive-unset /apps/panel
rm -rf ~/.gconf/apps/panel
pkill gnome-panel


W

Thursday, November 20, 2008

Ubuntu 7.10 + Git

I got curious and wanted to start playing with Git after hearing about it in the community for a while now. This is how I did it:

sudo apt-get install git

This will get the version 1.5.* from the Gutsy repos. This is old, so I decided to upgrade it.

git clone git://git.kernel.org/pub/scm/git/git.git

This will create a git folder. But first, we need to install some dependencies:

sudo apt-get install zlib1 zlib1-dev openssl libcurl3 libcurl3-dev libexpat1 libexpat1-dev asciidoc xmlto

Next, it's time to install Git. You can install Git either for the local user or for the global system. I decided to install it globally:

cd git
make configure
./configure
make all doc
sudo make install install-doc install-html

This should run for a while. You can sit back and pretend you understand all the output, or you can now go grab a coffee. After it completes, you can do a

git --version

to check if Git was updated. Now, time to play!


W

Sunday, November 16, 2008

|| and && operators may not be doing what you expect

When you use || and &&, you may think that you are playing with true/false values. For instance, a condition that uses || or && will give you back true or false.

I found out recently that this is sometimes true (and sometimes not)! Now, what am I talking about? I always thought that if you evaluate (true || true), the expression evaluates to true because at least one of them is true. Well, apparently, it does evaluate to true, but not for the reason I had thought.

In Ruby, when you evaluate (true || true), what it is actually doing is evaluating the first condition. If it is truthy (ie. not false or nil) you get the first condition back. If it is falsy (ie. false or nil), you get the second condition back. So the following occurs:

('blah' || true) #=> 'blah' - not true!
(false || 'blah') #=> 'blah' again!

For &&, if the first condition is falsy, you get the first condition back. If it is truthy, you get the second condition back. Check it out:

(true && 'blah') #=> 'blah'
(nil && true) #=> nil - not false!

Using || and && still work in 'if' statements as expected, but it doesn't work the way as first thought. With this new insight, you can use || and && for shortcuts.

Instead of:

if options[:product].nil?
product = Product.new
else
product = options[:product]
end

You could do:

product = options[:product] || Product.new

And instead of:

unless product.nil?
name = product.name
end

You coud do:

name = product && product.name

Obviously, use these shorthands with caution, as it can convolute readability for other readers. On another note, JavaScript also follows this evaluation. Have fun!


W

Tuesday, October 28, 2008

Thursday, October 23, 2008

Named Routes: Anchor

If you're using named routes and want to add an anchor to your automatically generated URL, there's a very simple way to do it:

products_path(:anchor => 'my_anchor')

It's that simple!


W

Tuesday, October 21, 2008

Being Lean

Here's an interesting article I'd like to share. It's about keeping your company fast and light:

http://venturehacks.com/articles/lean-startups


W

Monday, October 20, 2008

Interesting Ideas

Check out this talk by Jason Fried from 37signals. Definitely some very good ideas and insight.

http://www.balsamiq.com/blog/?p=375


W

Sunday, October 19, 2008

Textarea: Preserving Whitespace

A lot of the times when you let users post things using textareas, it becomes frustrating to lose whitespace when you display their posts (especially carriage returns).

Well, enter <pre>. This nifty little tag preserves any whitespace within the tags. However, there is one caveat. It preserves whitespace so well that it doesn't know how to word wrap. This is troublesome when your user continues to type in the textarea without hitting the carriage return. When displayed with the pre tags, the words are all on one long line.

Well, here's a nice little hack:

http://www.longren.org/2006/09/27/wrapping-text-inside-pre-tags/


W

Saturday, October 18, 2008

Ruby: Time made easy

Here's another example of how Ruby just makes things simple. Imagine you're working with time and you have to figure out the difference between 2 times and whether they fall within a certain range. In most languages, you have to figure out how many seconds exist in your time range. For example, 1 minute would have 60 seconds and 1 day would have 86,400 seconds. That's not too hard to figure out, but imagine the readability!

t2 - t1 < 86400

That just begs the question, "Where does 86400 come from?". Imagine you had to explicitly put down the number for 1 week?

Well, Ruby is awesome in that it concentrates on readability. Since everything in Ruby is an object, numbers are just Fixnum (or Bignum). Either way, that means we can use certain methods associated with the object. Check this out:

t2 - t1 < 1.second
t2 - t1 < 1.minute
t2 - t1 < 1.hour
t2 - t1 < 1.day
t2 - t1 < 1.week
t2 - t1 < 1.month
t2 - t1 < 1.year

Now how readable is that?


W

Friday, October 17, 2008

VMware Server: Adding a USB

Ever wondered how to add USB capability to your VMware server? Well, I had a little bit of a problem trying to get my USB connected.

I had gone to the settings for my VM and added the USB controller. Then, when I booted up my VM, I went to

VM > Removable Devices > USB Devices > ...

To my surpise, it was empty! I knew my device was plugged in because my Ubuntu detected it, but I couldn't see it. After searching around, I found a solution:

1. power off your VM
2. unplug your USB
3. >sudo gvim /etc/init.d/mountdevsubfs.sh
4. uncomment lines 42-45 (starts off with #mkdir -p /dev/bus/usb/.usbfs...)
5. >sudo /etc/init.d/mountdevsubfs.sh start
6. start your VM
7. plug in your USB
8. add your USB to the VM

Good luck!


W

Tuesday, September 30, 2008

initialize + super

Here's a word of caution to those using inheritance and calling super in the initialize method. Consider this:

def initialize(name, price)
super
@name = name
@price = price
end

Which parent method does it call? I was surprised to find out that without () after super, it automatically calls the initialize in the parent that has the parameters (name, price), rather than the one without parameters. If your intention was to call the parent's initialize without parameters, than you must do:

super()


W

Monday, September 29, 2008

TinyMCE: enforce maxlength

TinyMce doesn't have support for maxlength, and putting maxlength in the textfield tag won't do anything either.

If you try to google for a solution, you might come across this site

Don't waste your time on it, because the solution is built with the old tinymce api, it wouldn't work. Instead, use the solution from this post.


J

RoR: attr_accessible with attachment_fu

If you try to use attr_accessible on any model with attachment_fu plugin,
you'll get an error.

This article explains why


J

Sunday, September 28, 2008

RoR: attr_accessible

In a previous post, I talked about mass assignment. Well, there's something I discovered recently. If you have a polymorphic relationship, your model will have two columns: taggable_type and taggable_id. If you want to make these available for mass assignment, you cannot do:

attr_accessible taggable_type, taggable_id

Instead, RoR treats them like one attribute like so:

attr_accessible taggable


W

Saturday, September 27, 2008

RoR Generate + SVN

We all know about RoR's ability to generate controllers, models, migrations, etc. However, if you're using a repository, you have to manually add these newly created files. This could be a pain in the ass!

Here's a tip. If you're using SVN, you'll love this. Simply add the flag --svn and the generator will automatically add the newly created files to SVN. Simple!


W

Thursday, September 25, 2008

RoR: Mass Assignment Security

In RoR, it is possible to do something called mass assignments. For instance, when submitting a form, all the parameters are put into a params hash so you can do the following:

Product.create(params[:product])
product.update_attributes(params[:product])

Very simple, but by default, there is a security flaw. That flaw is covered in this post. If you are concerned about this, the easiest way would be to make it so that all your models will require attr_accessible on any attributes that you want mass assignment for. This then protects any attributes not listed by default.

In your config files, preferably in your initializers folder, add the following to protect all attributes:

ActiveRecord::Base.send(:attr_accessible, nil)

Then go through each model and think about which attributes should be exposed to mass assignments. For those that are not accessible, you must do the following to assign values:

product.store_id = store.id

This makes the assignment explicit and cannot be manipulated by the users.

Now that you know, go secure your applications!


W

Tuesday, September 23, 2008

Stack and Queue Implementation

Array in Ruby already has built in push and pop function you can use, but if you want to make it more strict and idiot proof, here's how you can implement it.

class Stack

def initialize
@stack = []
end

def push(x)
@stack.push(x)
end

def pop
@stack.pop unless is_empty?
end

def peek
@stack.last
end

def is_empty?
@stack.empty?
end

end

class Queue

def initialize
@queue = []
end

def enqueue(x)
@queue << x
end

def dequeue(x)
@queue.shift
end

def peek
@queue.first
end

def is_empty?
@queue.empty?
end

end


J

Fun with String

This is why Ruby is amazing :D

1. converting strings to numbers

"123".to_i => 123
Duh, everyone knows that

but how bout
"123stfu".to_i => 123

or

" 123stfu ".to_i => 123

you can even indicate the base of your conversion

"111".to_i(2) => 7 # treat it as a binary number
"111".to_i(8) => 73 # treat it as an octal

split a string and convert it to an interger

"123 456 789".split.map {|m| m.to_i} => [123, 456, 789]

2. Replacing text

we can implement the lame rot13 encryption scheme in one line :)

class String; def rot13; self.tr("A-Ma-mN-Zn-z", "N-Zn-zA-Ma-m");end;end

"Please hide this line".rot13 => "Cyrnfr uvqr guvf yvar"

3. Counting Characters

s1 = "abcabcabcde"
s1.count("c") => 3
s1.count("abc") => 9
s1.count(s1) => 11

count can handle negation

s1.count("^abc") => 2
s1.count("^a") => 8

and range of chars

s1.count("a-c") => 9
s1.count("^a-z") => 0

4. Reversing a String

Microsoft loves to ask interviewee to reverse the word order of a String during an interview, it takes around 15 - 20 lines to implement the function in Java or C++, but we can do it in one :)

phrase = "This is a joke"
phrase.split.reverse.join(" ") => "joke a is This"

so next time you goto an interview, asks if they'll let you do it in Ruby ;)

5. Removing Duplicate Characters

string = "aaaaaaaaaaaaaaaaaaa".squeeze => "a"
string = "aaaaaaaaaaaaaaaaaaB".squeeze => "aB"
string = "hehe....".squeeze(".") => "hehe."


J

List of reflective methods

I find the following commands very useful from time to time, but I kept forgetting their names. So I'm creating this post to help remind myself.

a.class
# returns the class of an object a

a.superclass
# returns the superclass of an object a

a.instance_of? A
# determines if a.class == A

a.is_a? A
#determines whether a is an instance of c, or of any of its subclass, or of any modules.

a.respond_to? :something
#determines if a has a public or protected method with the specified name.


J

Shuffling an Array

I just found a very interesting article about shuffling an array correctly!

http://adrianquark.blogspot.com/2008/09/how-to-shuffle-array-correctly.html

Enjoy!


W