/morph

Morph makes it easy to emerge Ruby class definitions at runtime. Mix with Hpricot for screen scrapping fun.

Primary LanguageRubyOtherNOASSERTION

Morph allows you to emerge class definitions via calling assignment methods; mix with Hpricot for screen scrapping fun.

Morph playing with Hpricot

Here’s example code showing Morph playing with Hpricot:

require 'hpricot'; require 'open-uri'; require 'morph'

class Hubbit
  include Morph  # allows class to morph

  def initialize name
    doc = Hpricot open("http://github.com/#{name}")

    (doc/'label').collect do |node|
      label = node.inner_text
      value = node.next_sibling.inner_text.strip

      morph(label, value)  # morph magic happening here!
    end
  end
end

def Hubbit name; Hubbit.new name; end

The model emerges from the data. Let’s start by looking up ‘why’:

why = Hubbit 'why'

What new methods do we have?

Hubbit.morph_methods # => ["email", "email=", "name", "name="]

Ah-ha, so we have a name attribute now:

why.name # => "why the lucky stiff"

Let’s add some of why’s projects:

why.projects = %w[shoes hacketyhack camping hoodwinkd hpricot
                 markaby mousehole parkplace poignant sandbox]

That why’s a productive fellow! Note new accessor methods have been added:

Hubbit.morph_methods
# => ["email", "email=", "name", "name=", "projects", "projects="]

Let’s do some more morphing:

dhh = Hubbit 'dhh'

Do we have more methods now?

Hubbit.morph_methods
# => ["blog", "blog=", "company", "company=", "email", "email=",
#    "location", "location=" "name", "name=", "projects", "projects="]

So, a new company method has appeared:

dhh.company #=> "37signals"

Morph making sample Active Record line via script_generate

Time to generate an Active Record model? Get a sample script line like this:

Hubbit.script_generate
# => "ruby script/destroy rspec_model Hubbit;
#    ruby script/generate rspec_model Hubbit blog:string company:string
#        email:string location:string name:string projects:string"

or specify the generator:

Hubbit.script_generate :generator => 'model'
# => "ruby script/destroy model Hubbit;
#     ruby script/generate model Hubbit blog:string company:string
#         email:string location:string name:string projects:string"

You’ll have to edit this as it currently sets all data types to be string, and doesn’t understand associations.

Morph setting hash of attributes via morph

class Order; include Morph; end
order = Order.new

How about adding a hash of attribute values?

order.morph :drink => 'tea', :spoons_of_sugar => 2, :milk => 'prefer soya thanks'

Looks like we got ‘em:

order.drink  # => "tea"
order.spoons_of_sugar  # => 2
order.milk  # => "prefer soya thanks"

Morph obtaining hash of attributes via morph_attributes

Create an item:

class Item; include Morph; end
item = Item.new
item.morph :name => 'spinach', :cost => 0.50

Now an order:

class Order; include Morph; end
order = Order.new
order.no = 123
order.items = [item]

Want to retrieve all that as a nested hash of values? No problem:

order.morph_attributes
# => {:items=>[{:name=>"spinach", :cost=>0.5}], :no=>123}

Last bits

See examples/ directory for some example code. See LICENSE for the terms of this software.

.                                                     ,
.                                                 ?7+~::+II~
.                                                ?7:     ,:+7
.                             777IIII777?        7:         :?7
.                          =I=           I:      7?          ,+7
.                         I?         ,,   77      7:           :I
.                        =  ?7777   77  7   7      7+,          :7
.                       7   777777 ~77+=77  I+      I?          ,7
.                      :7  77  ~77  I   I7   7       ?:          ?
.                      I   77   7,  7    7   :I       I          ?
.                      7   ?77=7~    77777    7      ~+          ,+
.                      7~                     7  :I7?~            7
.                      =?                     7 ?I    ~I77=       I=
.                       7    ?          :,   7  I7777,     7       7
.                        ?    777?~~7777+    7              7~      7
.                        ?7    ,777777=,   ,7                7      ,7
.                          7=      ,      =7                 7:      7
.                            +7         :7                    7      ,I
.                             :7        ?~                   7?       7
.                              7         7              ~II7~,        7
.                              7         7  ,  =7777777?+,,,         I=
.                            :7,          ~==,                       7
.                       II~,,                                     77~
.                    ,I?                                      +777
.                   7+,                                 ~7777:
.                 ==                               :77
.               :7:                              ,7I
.             7I                                 7
.            I          ,7,                      7
.          =7          77=7                      7
.        ,7          7I   7                      7
.        I,        I7     7                      7
.       ?,       ,7       7,                     7
.       7       7~        7,                     7
.       7      ,7I        7                      7
.       =+       =7       7                      ~=
.        =7        7,     7                       7
.         ,7,       ~7IIII7+,                     7
.           +:              II                    I
.            ?7              I?                   +~
.              II,           +I                    7
.                ~7          ,I                    7
.                  7=        ~7                    7
.                   ?7,     ~7+                    ?~
.                     ~7777I=                      ,7
.                         7:                        7
.                         I                         7
.                         I          ,:77I          7
.                         I          :7             I
.                         I                         =~
.                         7               ,         ,7
.                         +,         7    :         ,7
.                          +         7    +          7
.                          +         7    +         ,7
.                          7         I    ?         ,7
.                          7         +:   7         ,7
.                          7         =+   7         ,7
.                          7         :I   I         ,7
.                          7         :I   7          7
.                          7         :I   I          7
.                          I,        ,7   I:         7
.                          =+        ,7    ?         7
.                          :?,       ,7    7,        7
.                          I:        ,7    7,        ?
.                         :7         ,7    7,        ,
.                        +I,         :     ?         ,=
.                       +=           ~     =~         7
.                    :II,,           =      I         ?
.                =I=                 ?      7,        :7
.              II~                   I      7,         ,II
.            7~                      ~7     7            ,=7
.            =                       =7     I,             ::
.            77II?==?II777777777777777      7~              7
.                                            77+,,          7:
.                                               777777+:,~777
.