You are here: Browse Railsplugins Morph
Morph allows you to emerge class definitions via calling assignment methods; mix with Hpricot for screen scrapping fun.
Morph example 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
end
def initialize name
doc = Hpricot open("http://github.com/#{name}")
end
(doc/'label').collect do |node|
label = node.inner_text
value = node.next_sibling.inner_text.strip
end
morph(label, value) # morph magic happening here!
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 example from Hash
How about adding a hash of attribute values?
class Order; include Morph; end
order = Order.new
order.morph :drink => 'tea', :spoons_of_sugar => 2, :milk => 'prefer soya thanks'
order.drink # => "tea"
order.spoons_of_sugar # => 2
order.milk # => "prefer soya thanks"
Morph example hijacking method creation
class VegieFoxes include Morph end
def method_missing symbol, *args
if (is_writer = symbol.to_s =~ /=$/)
morph_method_missing(symbol, *args) do |base, attribute|
create_accessors base, attribute
end
send(symbol, *args)
else
super
end
end
private
def create_accessors base, attribute
base.class_eval "attr_reader :#{attribute}"
end
base.class_def("#{attribute}=") do |value|
is_meat = %w[bacon ham].include? value
value = is_meat ? 'spinach' : value
instance_variable_set "@#{attribute}".to_sym, value
end
foxes = VegieFoxes.new
foxes.chunky = ‘bacon’ foxes.inspect # => #<vegiefoxes>
foxes.chunky = ‘cheese’ puts foxes.inspect # => #<vegiefoxes>
foxes.pet = ‘ham’ foxes.inspect # => #<vegiefoxes>
Last bitsSee examples/ directory for some example code. See LICENSE for the terms of this software.
. ,
. ?7+~
. ?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= . 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
.
NOTE: This description has been extracted from the Plugin README and so the formatting may need updating to make browser friendly