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
.