Skip to content

Instantly share code, notes, and snippets.

@melborne
Created September 15, 2012 11:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save melborne/3727490 to your computer and use it in GitHub Desktop.
Save melborne/3727490 to your computer and use it in GitHub Desktop.
iPhone5 constructor for describing JavaScript prototype chain
function ObjectCreate (base, properties) {
function F () { };
F.prototype = base;
var obj = new F;
for(prop in properties) {
obj[prop] = properties[prop];
};
return obj;
};
var Twitter = {
tweet: function(words) {
return this.account + ": " + words;
},
retweet: function(at, words) {
return "@" + at + ": " + words;
}
};
var charlie = Object.create(Twitter, { account: { value: 'charlie' }});
charlie.tweet('JavaScriptなう!'); // 'charlie: JavaScriptなう!'
charlie.retweet('earl', 'JSのOOPって難しくね?'); // '@earl: JSのOOPって難しくね?'
var iPhone5 = {
call: function(number) {
return "Calling to " + number + " ...";
},
iTunes: function(title, artist) {
return "Playing: => `" + title + "` of " + artist;
},
camera: function() {
return this.name + " Take a Photo!";
},
panorama: function() {
return this.name + " Take a Panorama Photo!!";
}
};
var jonathan = Object.create(iPhone5, { id: { value: 12345 }, name: { value: 'Jonathan' }});
var scott = Object.create(iPhone5, { id: { value: 12346 }, name: { value: 'Scott' }});
jonathan.id; // 12345
jonathan.name; // 'Jonathan'
jonathan.call('800-692-7753'); // 'Calling to 800-692-7753 ...'
jonathan.iTunes('Imagine', 'John Lennon'); // 'Playing: => `Imagine` of John Lennon'
jonathan.panorama(); // 'Jonathan Take a Panorama Photo!!'
scott.id; // 12346
scott.name; // 'Scott'
scott.call('800-275-2273'); // 'Calling to 800-275-2273 ...'
scott.iTunes('My Hero', 'Foo Fighters'); // 'Playing: => `My Hero` of Foo Fighters'
scott.panorama(); // 'Scott Take a Panorama Photo!!'
require "graphaz"
top = "{ _proto_ }"
ip5 = "{ iPhone5 | :call\n :iTunes\n :camera\n :panorama\n _proto_ }"
f = "F | :prototype"
ip5_a, ip5_b, ip5_c = %w(jonathan scott peter).map { |id| "{ #{id} | :id :name\n _proto_ }" }
chains = [
"null => #{top}",
"#{top} => #{ip5}",
"#{ip5} => #{f}",
"#{f} => #{ip5_a}",
"#{f} => #{ip5_b}",
"#{f} => #{ip5_c}",
]
ga = GraphAz.new(:PrototypeChain)
ga[:label] = "JavaScript Prototype Chain\n Object.create"
ga.gnode[:shape] = 'Mrecord'
ga.gedge[:arrowhead] = 'none'
chains.each { |chain| ga.add chain }
ga.node(f, :shape => 'record', :style => 'dotted', :fillcolor => 'magenta')
ga.node(ip5, ip5_a, ip5_b, ip5_c, :style => 'bold', :color => 'magenta')
ga.node("null", :shape => 'plaintext', :style => 'dotted')
puts ga.print_graph
require "graphaz"
ip5 = "iPhone5 | :prototype"
ip5_a, ip5_b, ip5_c = %w(jonathan scott peter).map { |id| "{ #{id} | :id :name\n _proto_ }" }
top = "{ _proto_ }"
obj = "{ :call\n :iTunes\n :camera\n :panorama\n _proto_ }"
chains = [
"#{ip5} => #{ip5_a}",
"#{ip5} => #{ip5_b}",
"#{ip5} => #{ip5_c}",
"#{obj} => #{ip5}",
"#{top} => #{obj}",
"null => #{top}"
]
ga = GraphAz.new(:PrototypeChain)
ga[:label] = "JavaScript Prototype Chain"
ga.gnode[:shape] = 'Mrecord'
ga.gedge[:arrowhead] = 'none'
chains.each { |chain| ga.add chain }
ga.node(ip5, :shape => 'record', :style => 'filled', :fillcolor => 'magenta')
ga.node(ip5_a, ip5_b, ip5_c, :style => 'bold', :color => 'magenta')
ga.node("null", :shape => 'plaintext', :style => 'dotted')
puts ga.print_graph
require "graphaz"
ip5 = "iPhone5 | :prototype"
ip5_a, ip5_b, ip5_c = %w(jonathan scott peter).map { |id| "{ #{id} | :id :name\n _proto_ }" }
# proto = "{ prototype | :panorama }"
ip4 = "iPhone4 | :prototype"
ip4_a, ip4_b = %w(phil steve).map { |id| "{ #{id} | :id :name:\n _proto_ }" }
ip4_x = "{ :panorama\n _proto_}"
top = "{ _proto_ }"
obj = "{ :call\n :iTunes\n :camera\n _proto_ }"
chains = [
"#{ip5} => #{ip5_a}",
"#{ip5} => #{ip5_b}",
"#{ip5} => #{ip5_c}",
"#{ip4} => #{ip4_a}",
"#{ip4} => #{ip4_b}",
"#{ip4} => #{ip4_x}",
"#{ip4_x} => #{ip5}",
"#{obj} => #{ip4}",
"#{top} => #{obj}",
"null => #{top}"
]
ga = GraphAz.new(:PrototypeChain)
ga[:label] = "JavaScript Prototype Chain"
ga.gnode[:shape] = 'Mrecord'
ga.gedge[:arrowhead] = 'none'
chains.each { |chain| ga.add chain }
ga.node(ip5, :shape => 'record', :style => 'filled', :fillcolor => 'magenta')
ga.node(ip5_a, ip5_b, ip5_c, :style => 'bold', :color => 'magenta')
ga.node(ip4, :shape => 'record', :style => 'filled', :fillcolor => 'green')
ga.node(ip4_a, ip4_b, ip4_x, :style => 'bold', :color => 'green')
ga.node("null", :shape => 'plaintext', :style => 'dotted')
puts ga.print_graph
require "graphaz"
ip5 = "iPhone5 | :prototype"
ip5_a, ip5_b, ip5_c = %w(jonathan scott peter).map { |id| "{ #{id} | :id :name\n _proto_ }" }
ip4 = "iPhone4 | :prototype"
ip4_a, ip4_b = %w(phil steve).map { |id| "{ #{id} | :id :name:\n _proto_ }" }
ip4_x = "{ :panorama\n _proto_}"
ipad = "iPad | :prototype"
ipad_a = "{ tim | :id :name\n :call=x\n _proto_}"
ios = "iOS | :prototype"
ios_x = "{ :camera\n _proto_ }"
ios_y = "{ _proto_ }"
top = "{ __proto__ }"
obj = "{ :call\n :iTunes\n _proto_ }"
chains = [
"#{ip5} => #{ip5_a}",
"#{ip5} => #{ip5_b}",
"#{ip5} => #{ip5_c}",
"#{ip4} => #{ip4_a}",
"#{ip4} => #{ip4_b}",
"#{ip4} => #{ip4_x}",
"#{ip4_x} => #{ip5}",
"#{ios} => #{ios_x}",
"#{ios} => #{ios_y}",
"#{ios_x} => #{ip4}",
"#{ios_y} => #{ipad}",
"#{ipad} => #{ipad_a}",
"#{obj} => #{ios}",
"#{top} => #{obj}",
"null => #{top}"
]
ga = GraphAz.new(:PrototypeChain)
ga[:label] = "JavaScript Prototype Chain"
ga.gnode[:shape] = 'Mrecord'
ga.gedge[:arrowhead] = 'none'
chains.each { |chain| ga.add chain }
ga.node(ip5, :shape => 'record', :style => 'filled', :fillcolor => 'magenta')
ga.node(ip5_a, ip5_b, ip5_c, :style => 'bold', :color => 'magenta')
ga.node(ip4, :shape => 'record', :style => 'filled', :fillcolor => 'green')
ga.node(ip4_a, ip4_b, ip4_x, :style => 'bold', :color => 'green')
ga.node(ipad, :shape => 'record', :style => 'filled', :fillcolor => 'darkorange')
ga.node(ipad_a, :style => 'bold', :color => 'darkorange')
ga.node(ios, :shape => 'record', :style => 'filled', :fillcolor => 'deepskyblue')
ga.node(ios_x, ios_y, :style => 'bold', :color => 'deepskyblue')
ga.node("null", :shape => 'plaintext', :style => 'dotted')
ga.node(top, :label => '_proto_')
puts ga.print_graph
require "graphaz"
ip5 = "iPhone5 | :id :name\n :panorama"
ip5_a, ip5_b, ip5_c = %w(jonathan scott peter)
ip4 = "iPhone4 | :id :name\n :camera"
ip4_a, ip4_b = %w(phil steve)
ipad = "iPad | :id :name\n :call=x"
ipad_a = "tim"
ios_a = "iOS | :call\n :iTunes"
ios_b = "iOS | :call\n :iTunes 2"
top = "Object\n(BasicObject)"
chains = [
"#{ip5} => #{ip5_a}",
"#{ip5} => #{ip5_b}",
"#{ip5} => #{ip5_c}",
"#{ip4} => #{ip4_a}",
"#{ip4} => #{ip4_b}",
"#{ip4} => #{ip5}",
"#{top} => #{ip4}",
"#{top} => #{ipad}",
"#{ios_a} => #{ip4}",
"#{ios_b} => #{ipad}",
"#{ipad} => #{ipad_a}",
"null => #{top}"
]
ga = GraphAz.new(:ClassInheritance)
ga[:label] = "Ruby Class Inheritance"
ga.gnode[:shape] = 'Mrecord'
ga.gedge[:arrowhead] = 'none'
chains.each { |chain| ga.add chain }
ga.node(ip5, :shape => 'record', :style => 'filled', :fillcolor => 'magenta')
ga.node(ip5_a, ip5_b, ip5_c, :style => 'bold', :color => 'magenta')
ga.node(ip4, :shape => 'record', :style => 'filled', :fillcolor => 'green')
ga.node(ip4_a, ip4_b, :style => 'bold', :color => 'green')
ga.node(ipad, :shape => 'record', :style => 'filled', :fillcolor => 'darkorange')
ga.node(ipad_a, :style => 'bold', :color => 'darkorange')
ga.node(ios_a, ios_b, :shape => 'record', :style => 'bold', :color => 'deepskyblue')
ga.node(ios_b, :label => "iOS | :call\n :iTunes")
ga.node(top, :shape => 'record')
ga.node("null", :shape => 'plaintext', :style => 'dotted')
_top, _ip4, _ip5, _ipad = [top, ip4, ip5, ipad].map { |e| e.delete("\n ") }
# p _ip4, _ip5, _ipad
ga.edge("null_#{_top}", "#{_top}_#{_ip4}", "#{_top}_#{_ipad}", "#{_ip4}_#{_ip5}", :style => 'bold')
puts ga.print_graph
function iOS () { };
iOS.prototype = {
call: function(number) {
return "Calling to " + number + " ...";
},
iTunes: function(title, artist) {
return "Playing: => `" + title + "` of " + artist;
}
};
function iPhone4 (id, name) {
this.id = id;
this.name = name;
};
iPhone4.prototype = new iOS;
iPhone4.prototype.camera = function() {
return this.name + " Take a Photo!";
};
var phil = new iPhone4(10101, 'Phil');
phil.id; // 10101
phil.name; // 'Phil'
phil.call('408-974-5050'); // 'Calling to 408-974-5050 ...'
phil.iTunes('Valentine', 'Fiona Apple'); // 'Playing: => `Valentine` of Fiona Apple'
phil.camera(); // 'Phil Take a Photo!'
function iPhone5 (id, name) {
this.id = id;
this.name = name;
};
iPhone5.prototype = new iPhone4;
iPhone5.prototype.panorama = function() {
return this.name + " Take a Panorama Photo!!";
};
var jonathan = new iPhone5(12345, 'Jonathan');
var scott = new iPhone5(12346, 'Scott');
jonathan.id; // 12345
jonathan.name; // 'Jonathan'
jonathan.call('800-692-7753'); // 'Calling to 800-692-7753 ...'
jonathan.iTunes('Imagine', 'John Lennon'); // 'Playing: => `Imagine` of John Lennon'
jonathan.panorama(); // 'Jonathan Take a Panorama Photo!!'
scott.id; // 12346
scott.name; // 'Scott'
scott.call('800-275-2273'); // 'Calling to 800-275-2273 ...'
scott.iTunes('My Hero', 'Foo Fighters'); // 'Playing: => `My Hero` of Foo Fighters'
scott.panorama(); // 'Scott Take a Panorama Photo!!'
function iPad (id, name) {
this.id = id;
this.name = name;
this.call = function() { return 'not implemented yet'; };
};
iPad.prototype = new iOS;
var tim = new iPad(8765, 'Tim');
tim.id; // 8765
tim.name; // 'Tim'
tim.iTunes('Black Hourse And The Cherry Tree', 'KT Tunstall'); // 'Playing: => `Black Hourse And The Cherry Tree` of KT Tunstall'
tim.call('800-694-7466'); // 'not implemented yet'
module IOS
def call(number)
"Calling to #{number} ..."
end
def iTunes(title, artist)
"Playing: => `#{title}` of #{artist}"
end
end
class IPhone4
include IOS
attr_reader :id, :name
def initialize(id, name)
@id = id
@name = name
end
def camera
"#{name} Take a Photo!"
end
end
phil = IPhone4.new(10101, 'Phil');
phil.id # => 10101
phil.name # => "Phil"
phil.call('408-974-5050') # => "Calling to 408-974-5050 ..."
phil.iTunes('Valentine', 'Fiona Apple') # => "Playing: => `Valentine` of Fiona Apple"
phil.camera # => "Phil Take a Photo!"
class IPhone5 < IPhone4
attr_reader :id, :name
def initialize(id, name)
super
end
def panorama
"#{name} Take a Panorama Photo!!"
end
end
jonathan = IPhone5.new(12345, 'Jonathan')
scott = IPhone5.new(12346, 'Scott')
jonathan.id # => 12345
jonathan.name # => "Jonathan"
jonathan.call('800-692-7753') # => "Calling to 800-692-7753 ..."
jonathan.iTunes('Imagine', 'John Lennon') # => "Playing: => `Imagine` of John Lennon"
jonathan.panorama # => "Jonathan Take a Panorama Photo!!"
scott.id # => 12346
scott.name # => "Scott"
scott.call('800-275-2273') # => "Calling to 800-275-2273 ..."
scott.iTunes('My Hero', 'Foo Fighters') # => "Playing: => `My Hero` of Foo Fighters"
scott.panorama # => "Scott Take a Panorama Photo!!"
class IPad
include IOS
attr_reader :id, :name
def initialize(id, name)
@id, @name = id, name
end
def call(number)
"not implemented yet"
end
end
tim = IPad.new(8765, 'Tim')
tim.id # => 8765
tim.name # => "Tim"
tim.iTunes('Black Hourse And The Cherry Tree', 'KT Tunstall') # => "Playing: => `Black Hourse And The Cherry Tree` of KT Tunstall"
tim.call('800-694-7466') # => "not implemented yet"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment