Learning Regular Expressions

Learning Regular expressions require regular practice. Here are a few ways to practice:

  1. rails c
  2. Rubular

Any questions on this, please feel free to ask. We’re here to help…

Comments

How to Use Observer and Call Back

  • Add configuration
1
2
#config/application.rb
config.active_record.observers = :order_observer
  • Create a Observer Class
1
2
3
4
5
class OrderObserver < ActiveRecord::Observer
  def after_update(order)
    order.update_column('type_state', "UPDATED")
  end
end

or we can use the way to register

1
2
3
4
5
6
7
8
9
10
#config/application.rb
config.active_record.observers = :notification_observer

class NotificationObserver < ActiveRecord::Observer
  observe :account, :balance

  def after_update(order)
    order.update_column('type_state', "UPDATED")
  end
end

Any questions on this, please feel free to ask. We’re here to help…

Comments

How to Proxy a Domain to Localhost

  • STEP 1:

Edit your hosts file by typing:

1
sudo vim /etc/hosts

Add the following line to the file:

1
127.0.0.1 google.com (or whatever other hostname you want proxied)
  • STEP 2:

Type the following into the command line to (ip foward)set up the server port to 80 in this case it is 3000:

1
sudo ipfw add 100 fwd 127.0.0.1,3000 tcp from any to any 80 in

Any questions on this, please feel free to ask. We’re here to help…

Comments

Some Ruby on Rails Interview Questions

what’s N+1 problem, how to solve the problem

1
2
3
4
5
6
7
8
9
10
11
clients = Client.limit(10)

clients.each do |client|
  puts client.address.postcode
end

clients = Client.includes(:address).limit(10)

clients.each do |client|
  puts client.address.postcode
end

what’s the different with joins and includes

explain eager loading and lazy loading

how to get the top 10 average rating product name:

1
2
3
4
Product: name:string, id:integer,
Review: id:integer, rating:integer, product_id: integer
#solution
select p.name from products as p inner join review as r group by r.prouct_id order avg(r.rating) limit 10

using map and reduce to sum up 5 to 26 which is squareable

1
2
3
4
5
6
7
8
9
10
11
module SQ
  def square num
    num.times.each do |i|
      return true if i * i == num
    end
    false
  end
end

5.upto(26).inject(0){|sum,x|sum = sum + x if square(x);sum }
5.upto(26).inject(0){|sum,x|sum = sum + (square(x) ? x : 0 ) }

dynamic load

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module A
  def check_credit
    puts "A"
  end
end

module B
  def check_credit
    puts "B"
  end
end

class P
  attr_accessor :type
  def process
    #class_eval
    #self << class
      #include eval(type)
    #end
    type.constantize.check_credit

    check_credit
  end
end

Octopress No Lexer Error

just got error

/Users/ken/.rvm/gems/ruby-1.9.3-p327/gems/rubypython-0.5.3/lib/rubypython/rubypyproxy.rb:198:in `method_missing’: ClassNotFound: no lexer for alias ‘Ruby’ found (RubyPython::PythonError)

the problem is I put Ruby as syntax, It should be just ruby

Comments

Retry and Retry Code Blocks

simple way to rescue and retry several

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
tries = 0
begin
  # some routine
rescue
  tries += 1
  retry if tries <= 3
  puts "no dice!"
end
#or
3.times do
  begin
    ...
  rescue
    ...
  end
  break
end

with_rescue

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Integer
  def times_try
    n = self
    begin
      n -= 1
      yield
    rescue
      raise if n < 0
      retry
    end
  end
end

begin
  3.times_try do
    #some routine
  end
rescue
  puts 'no dice!'
end

if you don’t want to define

1
2
3
4
5
6
begin
  #your code
rescue
  retry if _r = (_r || 0) + 1 and _r < 4
  raise
end
1
2
3
4
5
6
7
with_rescue(ProtocolError, :limit => 5) do |try|
  if try == 0
    self.send('HTTP/1.1')
  else
    self.send('HTTP/1.0')
  end
end

Retry Block Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Options:
# * :tries - Number of retries to perform. Defaults to 1.
# * :on - The Exception on which a retry will be performed. Defaults to Exception, which retries on any Exception.
#
# Example
# =======
#   retryable(:tries => 1, :on => OpenURI::HTTPError) do
#     # your code here
#   end
#
def retryable(options = {}, &block)
  opts = { :tries => 1, :on => Exception }.merge(options)

  retry_exception, retries = opts[:on], opts[:tries]

  begin
    return yield
  rescue retry_exception
    retry if (retries -= 1) > 0
  end

  yield
end

us it as

1
2
3
4
retryable(:tries => 5, :on => OpenURI::HTTPError) do
  open('http://example.com/flaky_api')
  # Code that mashes up stuff for your "social networking" site.
end

Here are the Kernel#retryable specs (pastie).

Comments

Webkit and Rspec Without X Server

capybara-webkit

problems running capybara-webkit with the Headless gem, Xvfb and our ci server. We use this setup for automatic integration testing and javascript testing of our Ruby on Rails 3.2 app. During the tests it complains that

webkit_server: cannot connect to X server need to rspec to config as:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'rspec/autorun'
require 'capybara/rspec'
require 'capybara/webkit'
require 'headless'

Capybara.register_driver :webkit do |app|
  Capybara::Driver::Webkit.new(app, :ignore_ssl_errors => true)
end

Capybara.javascript_driver = :webkit

# don't run on the local machine (since we don't have xvfb running locally)
if Rails.env.production?
    headless = Headless.new
    headless.start
end

Ruby Selenium-webdriver Watir-webdriver

There are many other Selenium gems out there, but this is the only official, maintained gem. If you’re looking for a slightly higher level API built on the same technology, you may want to check out watir-webdriver or capybara.

example code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
require "selenium-webdriver"

driver = Selenium::WebDriver.for :firefox
driver.navigate.to "http://google.com"

element = driver.find_element(:name, 'q')
element.send_keys "Hello WebDriver!"
element.submit

puts driver.title

driver.quit

# execute arbitrary javascript
puts driver.execute_script("return window.location.pathname")

# pass elements between Ruby and JavaScript
element = driver.execute_script("return document.body")
driver.execute_script("return arguments[0].tagName", element) #=> "BODY"

# wait for a specific element to show up
wait = Selenium::WebDriver::Wait.new(:timeout => 10) # seconds
wait.until { driver.find_element(:id => "foo") }

# switch to a frame
driver.switch_to.frame "some-frame" # name or id
driver.switch_to.frame driver.find_element(:id, 'some-frame') # frame element

# switch back to the main document
driver.switch_to.default_content

# repositionning and resizing browser window:
driver.manage.window.move_to(300, 400)
driver.manage.window.resize_to(500, 800)
driver.manage.window.maximize

# get an attribute
class_name = element.attribute("class")

# is the element visible on the page?
element.displayed?

# click the element
element.click

# get the element location
element.location

# scroll the element into view, then return its location
element.location_once_scrolled_into_view

# get the width and height of an element
element.size

# press space on an element - see Selenium::WebDriver::Keys for possible values
element.send_keys :space

# get the text of an element
element.text

SSL Certificates

The Firefox driver ignores invalid SSL certificates by default. If this is not the behaviour you want, you can do:

1
2
3
4
profile = Selenium::WebDriver::Firefox::Profile.new
profile.secure_ssl = true

driver = Selenium::WebDriver.for :firefox, :profile => profile

There is an edge case where the default SSL certificate check will not work correctly. WebDriver assumes that the certificate is untrusted whenever there’s a problem, which means a certificate from a trusted issuer but with a hostname mismatch (e.g. a production certificate in a test environment) will not be correctly ovverriden. See UntrustedSSLCertificates for more on why this is. To work around it, tell the Firefox driver to not assume the issuer is untrusted:

1
2
3
profile = Selenium::WebDriver::Firefox::Profile.new
profile.assume_untrusted_certificate_issuer = false
driver = Selenium::WebDriver.for :firefox, :profile => profile

Not that Profile#secure_ssl remains set to the default value of true in the above example.

Create Ruby Dynamic Class

1
2
3
4
5
dynamic_name = "TestEval2"

Object.const_set(dynamic_name, Class.new)
dummy2 = eval("#{dynamic_name}")
puts "dummy2: #{dummy2}"
1
2
3
dynamic_name = "ClassName"
Object.const_set(dynamic_name, Class.new { def method1() 42 end })
ClassName.new.method1 #=> 42
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class_name = 'foo'.capitalize
klass = Object.const_set(class_name,Class.new)

names = ['instance1', 'instance2'] # Array of instance vars

klass.class_eval do
  attr_accessor *names

  define_method(:initialize) do |*values|
    names.each_with_index do |name,i|
      instance_variable_set("@"+name, values[i])
    end
  end
  # more...
end

class_eval and const_set are used.

1
2
3
4
5
6
7
8
9
10
11
12
a_new_class = Class.new(Object) do
  attr_accessor :x

  def initialize(x)
    print #{self.class} initialized with #{x}"
    @x = x
  end
end

SomeModule.const_set("ClassName", a_new_class)

c = ClassName.new(10)

without class_eval and const_set You don’t really need to use const_set. The return value of Class.new can be assigned to a constant and the block of Class.new is class_eval.

1
2
3
4
5
6
7
8
9
ass Ancestor; end
SomeClass = Class.new(Ancestor) do
  def initialize(var)
     print "#{self.class} initialized with #{var}"
  end
end
=> SomeClass
SomeClass.new("foo")
# SomeClass initialized with foo=> #<SomeClass:0x668b68>

The following code uses a class factory to create a new class along with getter and setters for the fields passed into it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class ClassFactory
  def self.create_class(new_class, *fields)
    c = Class.new do
      fields.each do |field|
        define_method field.intern do
          instance_variable_get("@#{field}")
        end
        define_method "#{field}=".intern do |arg|
          instance_variable_set("@#{field}", arg)
        end
      end
    end

    Kernel.const_set new_class, c
  end
end

ClassFactory.create_class "Car", "make", "model", "year"

new_class = Car.new
new_class.make = "Nissan"
puts new_class.make # => "Nissan"
new_class.model = "Maxima"
puts new_class.model # => "Maxima"
new_class.year = "2001"
puts new_class.year # => "2001"

In Ruby, classes are simply objects like any other, which are then assigned to a constant. Hence, to create a new class dynamically we instantiate the class Class with Class.new, and then assign it to a constant via const_set (we invoke it on Kernel so that it is a top-level constant like any other class). We then add the code that makes up the class in a do-end block.

In that do-end block, for each field we invoke define_method twice, first for the getter method and then the setter method with get_instance_variable and set_instance_variable, respectively. For each field, we create the instance variables (e.g., for make, we use @make). Note how we make use of passing the argument in for the setter.

Additionally, if I wanted to make the class a sub-class, I could have used Class.new(parent_class)

Basic Metaprogramming Ruby Class_eval and Instance_eval

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class A

  def create_method(name)
    self.class.instance_eval do
      define_method(name) { puts "Nice!  I'm #{name}" }
      def human?
        true
      end
    end
  end

  def create_class_method(name)
    self.class.instance_eval do
      self.class.send( :define_method, name) { puts "Nice!  I'm #{name}" }
    end
  end

  def create_instance_method(name)
    (class << self; self; end).class_eval do
      #self.class.send( :define_method, name) { puts "Nice!  I'm #{name}" }
      define_method(name) { puts "Nice!  I'm #{name}" }
    end
  end

Sometimes when the book explains a concept or Ruby feature, it sheds light on things I’ve seen in other people’s code – things I’ve always wondered about. One such example is class_eval and instance_eval. These methods allow you to evaluate arbitrary code in the context of a particular class or object. They’re slightly similar to call, apply and bind in JavaScript, in that you are altering the value of self (this in JavaScript) when you use them. Let’s take a look at some examples to demonstrate their usage.

1
2
3
4
5
6
7
8
9
10
11
class Person
end

Person.class_eval do
  def say_hello
   "Hello!"
  end
end

jimmy = Person.new
jimmy.say_hello # "Hello!"

In this example, class_eval allows us to define a method within the Person class outside of its original definition and without reopening the class with the standard syntax. This could be useful when the class you want to add this method to is not known until runtime.

1
2
3
4
5
6
7
8
class Person
end

Person.instance_eval do
  def human?
    true
  end
end

Person.human? # true This example of instance_eval is similar, but evaluates the code in the context of an instance instead of a class. This is confusing at first, because in these examples class_eval creates instance methods and instance_eval creates class methods. There is reason behind the madness, however.

class_eval is a method of the Module class, meaning that the receiver will be a module or a class. The block you pass to class_eval is evaluated in the context of that class. Defining a method with the standard def keyword within a class defines an instance method, and that’s exactly what happens here.

instance_eval, on the other hand, is a method of the Object class, meaning that the receiver will be an object. The block you pass to instance_eval is evaluated in the context of that object. That means that Person.instance_eval is evaluated in the context of the Person object. Remember that a class name is simply a constant which points to an instance of the class Class. Because of this fact, defining a method in the context of Class instance referenced by Person creates a class method for Person class.

It may be difficult to wrap your mind around that if you’re not familiar with the Ruby object model, but it’s still easy to remember how these methods behave with a simple mnemonic device: when called on a class name constant, these two methods will allow you to create methods of the opposite type from their names. MyClass.class_eval will create instance methods and MyClass.instance_eval will create class methods.

If you’re interested in metaprogramming or understanding the Ruby object model, I’d definitely recommend the book. It’s helped me out tremendously.

I did some experiment with meta programming keywords “class_eval” and “instance_eval’. Sharing some of the examples with you all -

class_eval opens the existing class and adds the methods as defined in an ordinary class, hence they work as instance methods of that class

1
2
3
4
5
6
7
String.class_eval do
  def quack
    p 'quack method'
  end
end

"any string".quack

A method defined for class A using class_eval will work as instance method of A

1
2
3
4
5
6
7
8
9
10
class A
end

A.class_eval do
  def some_method
    p 'some_method'
  end
end

A.new.some_method

instance_eval on a class will open the class as an instance of class Class. Any method defined will be treated as the method of this instance which is the class. Hence the methods work like class methods

1
2
3
4
5
6
7
8
9
10
class A
end

A.instance_eval do
  def other_method
    p 'other_method'
  end
end

A.other_method

instance_eval on an instance of a class will open that instance of the class. Thus it works like a singleton method that is specific to the instance and wont work for other instances of the class

1
2
3
4
5
6
7
8
9
10
11
12
13
class A
end

a = A.new
a.instance_eval do
  def a_method
    p 'a_method'
  end
end

a.a_method  # works for 'a' on which the instance_eval is defined
b = A.new
b.a_method  # doesn't work for 'b'

This is the same as calling instance_eval on the instance ‘a’ of class A. This again will define a singleton method on the instance

1
2
3
4
5
6
7
8
class << a
  def show
    p 'this is a method'
  end
end
a  = A.new
a.show
b.show  # doesn't work for 'b'

Can not call ‘class_eval’ on an instance. class_eval can only be called on classes (which are instances of class Class)

1
2
3
4
5
6
7
8
9
10
11
12
class A
end

a.class_eval do
  def show_other
    p 'this is another method'
  end
end

a = A.new
a.show
b.show