Date post: | 04-Jun-2018 |
Category: |
Documents |
Upload: | netza-lopez |
View: | 215 times |
Download: | 0 times |
of 109
8/14/2019 Ruby Bits Slides
1/109
E X P R E S S I O N S
8/14/2019 Ruby Bits Slides
2/109
Bad Code
I C O N S
Worse Code
Good Code
Awesome Code
8/14/2019 Ruby Bits Slides
3/109
Unless is more intuitive
U N L E S S
if ! tweets.empty? puts "Timeline:" puts tweetsend
unless tweets.empty? puts "Timeline:" puts tweetsend
8/14/2019 Ruby Bits Slides
4/109
Unless with else is confusing
U N L E S S W I T H E L S E
unless tweets.empty? puts "Timeline:"
puts tweets
end
else puts "No tweets found - better follow some people!"
if tweets.empty? puts "No tweets found - better follow some people!"else puts "Timeline:" puts tweetsend
8/14/2019 Ruby Bits Slides
5/109
nil treated as false
N I L I S FA L S E ! Y
if attachment.file_path != nil attachment.postend
if attachment.file_path attachment.postend
8/14/2019 Ruby Bits Slides
6/109
treated as true!
O N LY N I L I S FA L S E ! Y
""
treated as true!0
treated as true![]
unless name.length warn "User name required"end
wil l ne ve r be f al s e !
8/14/2019 Ruby Bits Slides
7/109
try inline if/unless
I N L I N E C O N D I T I O N A L S
if password.length < 8 fail "Password too short"
end
fail "Password too short" if password.length < 8
unless username fail "No user name set"end
fail "No user name set" unless username
8/14/2019 Ruby Bits Slides
8/109
use && instead
S H O RT ! C I R C U I T ! A N D
if user
if user i f us e r is n i l
s e c o nd ha l f ne v
if user.signed_in? #... end
&& user.signed_in?
end
#...end
8/14/2019 Ruby Bits Slides
9/109
1
S H O RT ! C I R C U I T A S S I G N M E N T
result = nil || 1
result = 1 || nil
result = 1 || 2
1
1
8/14/2019 Ruby Bits Slides
10/109
if nil, default to empty array
D E FA U LT VA L U E S ! O R
tweets = timeline.tweets || []
tweets = timeline.tweetstweets = [] unless tweets
8/14/2019 Ruby Bits Slides
11/109
not evaluated unless
current session is nil
S H O RT ! C I R C U I T E VA L U AT I O N
def sign_in current_session || sign_user_inend
bu t co nsi d er w h et h er i f / t h en w o u l d be mo r e l e g i bl e!
8/14/2019 Ruby Bits Slides
12/109
i_was_set = 1
C O N D I T I O N A L A S S I G N M E N T
ass i g ns I F t he re s
n o e x is t i n g va l ue
i_was_not_set ||= 2
i_was_set ||= 2
puts i_was_set
puts i_was_not_set
1
2
8/14/2019 Ruby Bits Slides
13/109
use conditional assignment
C O N D I T I O N A L A S S I G N M E N T
options[ :country ] ||= 'us'options[ :privacy ] ||= trueoptions[ :geotag ] ||= true
options[ :country ] = 'us' if options[ :country ].nil?options[ :privacy ] = true if options[ :privacy ].nil?options[ :geotag ] = true if options[ :geotag ].nil?
8/14/2019 Ruby Bits Slides
14/109
if list_name "/#{user_name}/#{list_name}"else "/#{u ser_name}"end
assign the value of the if statement
C O N D I T I O N A L R E T U R N VA L U E S
options[ :path ] =
if list_name options[ :path ] = "/#{user_name}/#{list_name}"else options[ :path ] = "/#{user_name}"end
http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/8/14/2019 Ruby Bits Slides
15/109
def list_url ( user_name, list_name )
C O N D I T I O N A L R E T U R N VA L U E S
"https://twitter.com/#{user_name}"
"https://twitter.com/#{user_name}/#{list_name}"if list_name
url =else
url =endurl
end
http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/8/14/2019 Ruby Bits Slides
16/109
C O N D I T I O N A L R E T U R N VA L U E S
def list_url ( user_name, list_name )if list_name
"https://twitter.com/#{user_name}/#{list_name}"else
"https://twitter.com/#{user_name}"end
end
http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/http://livepage.apple.com/8/14/2019 Ruby Bits Slides
17/109
C A S E S TAT E M E N T VA L U E
client_url = case client_namewhen "web"
"http://twitter.com"when "Facebook"
"http://www.facebook.com/twitter"else
nilend
http://www.facebook.com/twitterhttp://www.facebook.com/twitterhttp://twitter.com/http://twitter.com/8/14/2019 Ruby Bits Slides
18/109
when
when
else
nil
end
popularity = case tweet.retweet_count0.. 9
10 .. 99"trending"
"hot"
C A S E ! R A N G E S
8/14/2019 Ruby Bits Slides
19/109
C A S E ! R E G E X P S
:mention
:direct_message
:publicelse
end
tweet_type = case tweet.statuswhen / \A @\w +/
when / \A d\s +\w +/
8/14/2019 Ruby Bits Slides
20/109
C A S E ! W H E N / T H E N
:mention:direct_message:public
end
tweet_type = case tweet.statusthenthen
when / \A @\w +/when / \A d\s +\w +/else
8/14/2019 Ruby Bits Slides
21/109
E X P R E S S I O N S
8/14/2019 Ruby Bits Slides
22/109
M E T H O D S A N D C L A S S E S
8/14/2019 Ruby Bits Slides
23/109
location isnt always used
O P T I O N A L A R G U M E N T S
def tweet ( message, lat, long ) #...
endtweet( "Practicing Ruby-Fu!" , nil , nil )
tweet( "Practicing Ruby-Fu!" )
location is now optiona
= nil = nil
, so lets add defdef tweet ( message, lat , long ) #...end
8/14/2019 Ruby Bits Slides
24/109
long parameter list
N A M E D A R G U M E N T S ! H A S H
tweet( "Practicing Ruby-Fu!" , 28.55 , - 81.33 , 227946 )
tweet( "Practicing Ruby-Fu!" , nil , nil , 227946 )
calls to it are hard
have to keep placeholders for
arguments youre not using
= nil = nildef tweet ( message, lat , long )reply_id = nil, #...
end
8/14/2019 Ruby Bits Slides
25/109
H A S H A R G U M E N T S
status = Status . new
status.lat = options[ :lat ] status.long = options[ :long ] status.body = message status.reply_id = options[ :reply_id ] status.postend
hash
reference keysfrom hash
def tweet ( message, options = {} )
8/14/2019 Ruby Bits Slides
26/109
H A S H A R G U M E N T S
tweet( "Practicing Ruby-Fu!" , :lat => 28.55 , :long => - 81.33 , :reply_id => 227946) keys show meaning
all combined intooptions argument
def tweet ( message, options = {} )
8/14/2019 Ruby Bits Slides
27/109
N A M E D A R G U M E N T S ! H A S H
C O M B O X 3 !
Repositioning the keys
Using Ruby 1.9 hash syntax
C O M B O X 2 !
tweet( "Practicing Ruby-Fu!" ,
lat: 28.55 ,long: - 81.33 ,reply_id: 227946
)
tweet( "Practicing Ruby-Fu!" ,
lat: 28.55,
long: - 81.33,
reply_id: 227946
)
N A M E D A R G U M E N T S H A S H
8/14/2019 Ruby Bits Slides
28/109
N A M E D A R G U M E N T S ! H A S H
C O M B O X 4 !
tweet( "Practicing Ruby-Fu!" )C O M B O X 5 !
Keys are optional
Complete hash is optional
tweet( "Practicing Ruby-Fu!" ,reply_id: 227946
)
E X C E P T I O N S
8/14/2019 Ruby Bits Slides
29/109
E X C E P T I O N S
if tweets.empty?
magic return value
cant be sure its an error
endend
[]else
list.tweetsif list.authorized?( @user )
def get_tweets ( list )
end
alert "No tweets were found!" + "Are you authorized to access this list?"
tweets = get_tweets(my_list)
E X C E P T I O N S
8/14/2019 Ruby Bits Slides
30/109
E X C E P T I O N S
raise an Exception instead
caller KNOWS theres a problem
def get_tweets ( list )unless list.authorized?( @user )
raise AuthorizationException . newendlist.tweets
end
begintweets = get_tweets(my_list)
rescue AuthorizationExceptionwarn "You are not authorized to access this list."
end
S P L AT A R G U M E N T S
8/14/2019 Ruby Bits Slides
31/109
def mention ( status, *names ) tweet( "#{names.join(' ')} #{status}" )end
S P L AT A R G U M E N T S
mention( 'Your courses rocked!' , 'eallam' , 'greggpollack' , 'jasonvanlu
status names[0] names[1] names[2]
eallam greggpollack jasonvanlue Your courses rocked!
Y O U N E E D A C L A S S W H E N
8/14/2019 Ruby Bits Slides
32/109
Y O U N E E D A C L A S S W H E N . . .
Kutcher, AshtonWheaton, Wil, Madonna
your users shouldnthave to deal withedge cases
O U T P U T:
user_names = [ [ "Ashton" , "Kutcher" ], [ "Wil" , "Wheaton" ], [ "Madonna" ]]user_names.each { | n| puts "#{n[ 1]}, #{n[ 0]}" }
Y O U N E E D A C L A S S W H E N
8/14/2019 Ruby Bits Slides
33/109
Y O U N E E D A C L A S S W H E N . . .
class Name def initialize ( first, last = nil )
@first = first @last = last end def format [ @last , @first ].compact.join( ', ' ) endend
behavior!
state!
Y O U N E E D A C L A S S W H E N
8/14/2019 Ruby Bits Slides
34/109
Y O U N E E D A C L A S S W H E N . . .
user_names = []user_names
8/14/2019 Ruby Bits Slides
35/109
O V E R S H A R I N G ?
shouldnt be able to do this!
def baz= ( valu @baz = valueenddef baz @bazend
attr_accessorclass Tweet attr_accessor :status , :created_at def initialize ( status ) @status = status @created_at = Time . new endend
tweet = Tweet . new( "Eating breakfast." )tweet.created_at = Time . new( 2084 , 1, 1, 0, 0, 0, "-07:00" )
O V E R S H A R I N G ?
8/14/2019 Ruby Bits Slides
36/109
O V E R S H A R I N G ?
doesnt define asetter!
undefined method 'created_at='
class Tweet attr_accessor :status
:created_at def initialize ( status ) @status = status @created_at = Time . new endend
attr_reader
tweet = Tweet . new( "Eating breakfast." )tweet.created_at =
Time . new( 2084 , 1, 1, 0, 0, 0, "-07:00" )
R E ! O P E N I N G C L A S S E S
8/14/2019 Ruby Bits Slides
37/109
R E O P E N I N G C L A S S E S
not so r eada
tweet = Tweet . new( "Eating lunch." )puts tweet.to_s
#
class Tweet def to_s "#{ @status }\n #{ @created_at }" endendtweet = Tweet . new( "Eating lunch." )puts tweet.to_s
so just r e
class and
Eating lunch.
2012-08-02 12:20:02 -0700
R E ! O P E N I N G C L A S S E S
8/14/2019 Ruby Bits Slides
38/109
R E O P E N I N G C L A S S E S
You can re-open and change any class.
Beware! You don't know who relies on the old functionality
You should only re-open classes that you yourself own.
S E L F
8/14/2019 Ruby Bits Slides
39/109
S E L F
class UserList attr_accessor :name def initialize ( name ) name = name endend
class UserList
attr_accessor :name def initialize ( name ) self .name = name endend
list = UserList . new ( 'celebrities'list.name
nil th is j us t re -se ts the
na me loca l va r iab le!
b u t th is ca l ls na me=
o n the c u r re n t ob jec t
list = UserList . new ( 'celebrities'
list.name
"celebrities"
8/14/2019 Ruby Bits Slides
40/109
M E T H O D S A N D C L A S S E S
8/14/2019 Ruby Bits Slides
41/109
C L A S S E S
E N C A P S U L AT I O N
8/14/2019 Ruby Bits Slides
42/109
def send_tweet ( status, owner_id ) retrieve_user(owner_id) ...end
send_tweet( "Practicing Ruby-Fu!" , 14 )
should not be responsible for retrieving a user
E N C A P S U L AT I O N
8/14/2019 Ruby Bits Slides
43/109
Passing around data as strings and numbers breaks encapsula
Places using that data need to know how to handle it.
Individual changes require updates at various places.
E N C A P S U L AT I O N
8/14/2019 Ruby Bits Slides
44/109
one parameter!
class Tweet attr_accessor ...
def owner retrieve_user(owner_ endend
tweet = Tweet . newtweet.status = "Practicing Ruby-Fu!"tweet.owner_id = current_user.id
send_tweet(tweet)
def send_tweet ( message ) message.owner ...end
E N C A P S U L AT I O N
8/14/2019 Ruby Bits Slides
45/109
May not be worth the overhead of a class if all you have is d
An option hash might su! ce.
When you have behavior to go with the data, it's time to intro
V I S I B I L I T Y
8/14/2019 Ruby Bits Slides
46/109
joe = User . new 'joleo = User . new 'le
joe.up_vote(leo)
class User
def up_vote ( friend )
bump_karma friend.bump_karma end
def bump_karma puts "karma up for #{name} "end
should not be partof the public API
karma up fkarma up f
end
V I S I B I L I T Y
8/14/2019 Ruby Bits Slides
47/109
joe = User . new 'joleo = User . new 'le
joe.up_vote(leo)
def bump_karma puts "karma up for #{name} "end
privateprivate method 'bumfor #
8/14/2019 Ruby Bits Slides
48/109
joe = User . new 'joleo = User . new 'le
joe.up_vote(leo)
def bump_karma puts "karma up for #{name} "end
protected
karma up fkarma up f
hidden from outsfrom other instan
class User
def up_vote ( friend )
bump_karma friend.bump_karma end
end
I N H E R I TA N C E
8/14/2019 Ruby Bits Slides
49/109
d u p l ica ted f u nc t io
attr_accessor :title , :size , :url
attr_accessor :title , :size , :url
def to_s "#{ @title }, {@size}" end
class Image
end
class Video
end
def to_s"#{ @title }, {@size}"
end
I N H E R I TA N C E
8/14/2019 Ruby Bits Slides
50/109
m uch D R Ye r!
attr_accessor :title , :size , :url
class Image < Attachmentend
class Video < Attachmentend
class Video < Atta attr_accessor
end
if a me thod o n l yse nse fo r o ne
p u t i t the re.
class Attachment
def to_s"#{ @title }, #{ @size }"
endend
S U P E R
8/14/2019 Ruby Bits Slides
51/109
class User def initialize ( name ) @name = name endend
follower = Follower . new( "Oprah" , "aplusk" )follower.relationship
" follows aplusk" n o @ na me!
d oes n t ca l l
Use r # i n i t ia l ize
class Follower < User def initialize ( name, following ) @following = following end def relationship "#{ @name} follows #{ @following } endend
S U P E R
8/14/2019 Ruby Bits Slides
52/109
class User def initialize ( name ) @name = name endend Ca l ls
Us e r # i n i t ia l iz e
class Follower < User def initialize ( name, following ) @following = following
end def relationship "#{ @name} follows #{ @following } endend
super (name)
follower = Follower . new( "Oprah" , "aplusk" )follower.relationship
"Oprah follows aplusk"
S U P E R
8/14/2019 Ruby Bits Slides
53/109
class Parent < Grandparentend
child = Child . newputs child.my_method
not he r e Grandparent: my_methodChild: my_method called
class Grandparentdef my_method
"Grandparent: my_method called"end
end
class Child < Parentdef my_method
string = super"#{string} \n Child: my_method called"
endend
S U P E R
8/14/2019 Ruby Bits Slides
54/109
Grandparent: 'w00t!Child: 'w00t!'
sa me as s u pe r (a r g u me n t )
class Grandparentdef my_method ( argument )
"Grandparent: '#{argument}'"
endend
class Child < Parentdef my_method ( argument )
string = super
"#{string} \n Child: '#{argument}'"end
end
child = Child . newputs child.my_method(
O V E R R I D I N G M E T H O D S
8/14/2019 Ruby Bits Slides
55/109
t y p ica l case
the oddba l lthumbnail
player
class Attachment def preview
endend
Th is is s lo w
case @typewhen :jpg , :png , :gif
when :mp3
end
O V E R R I D I N G M E T H O D S
8/14/2019 Ruby Bits Slides
56/109
thumbnail player
class Attachment def preview
endend the defa u l t s pec ia l h
a nd l i
class Audio < Attachment def preview
endend
H I D E I N S TA N C E VA R I A B L E S
8/14/2019 Ruby Bits Slides
57/109
a l ot of r epetition when wor kin g with these...
class Userdef tweet_header
[ @first_name , @last_name ].join( ' ' )
def profile[ @first_name , @last_name ].join( ' ' ) + @description
endend
end
H I D E I N S TA N C E VA R I A B L E S
8/14/2019 Ruby Bits Slides
58/109
you can use an accessor met hod , even wit hin t he same cl ass
class User
def tweet_header
[ @first_name , @last_name ].join( ' ' )
enddef profile
+ @description endend
display_name
display_name
def display_name
end
H I D E I N S TA N C E VA R I A B L E S
8/14/2019 Ruby Bits Slides
59/109
class User def display_name title = case @gender when :female married? ? "Mrs." : "Miss" when :male "Mr." end [title, @first_name , @last_name ].join( ' ' ) endend
if you need to chan ge the lo gic
lou can do it in just one place!
C O M B O X
8/14/2019 Ruby Bits Slides
60/109
8/14/2019 Ruby Bits Slides
61/109
A C T I V E S U P P O R T
A C T I V E S U P P O RT
8/14/2019 Ruby Bits Slides
62/109
Install It
$ gem install activesupport$ gem install i18n
Load It
require 'active_support/all'
not a depebut it is h
C O R E E X T E N S I O N S : A R R AY
8/14/2019 Ruby Bits Slides
63/109
p ad s r emoves t he el ement i t spl i t s on
array = [ 0, 1, 2, 3, 4, 5, 6]
array.from( 4)array.to( 2)array.in_groups_of( 3)array.split( 2)
[4, 5, 6][0, 1, 2][[0, 1, 2], [3, 4, 5], [6, nil, nil]][[0, 1], [3, 4, 5, 6]]
C O R E E X T E N S I O N S : D AT E
8/14/2019 Ruby Bits Slides
64/109
Fri, 21 Dec 2012 14:27:45 +0000
apocalypse = DateTime . new( 2012 , 12 , 21 , 14 , 27 , 45 )
Fri, 21 Dec 2012 00:00:00 +0000
apocalypse.at_beginning_of_day
Mon, 31 Dec 2012 23:59:59 +0000
apocalypse.at_end_of_month
Sun, 01 Jan 2012 00:00:00 +0000
apocalypse.at_beginning_of_year
C O R E E X T E N S I O N S : D AT E
8/14/2019 Ruby Bits Slides
65/109
Fri, 21 Dec 2012 14:27:45 +0000
apocalypse = DateTime . new( 2012 , 12 , 21 , 14 , 27 , 45 )
Wed, 05 Apr 2017 14:27:45 +0000
apocalypse.advance( years: 4, months: 3, weeks: 2, days: 1)
Sat, 22 Dec 2012 14:27:45 +0000
apocalypse.tomorrow
Thu, 20 Dec 2012 14:27:45 +0000
apocalypse.yesterday
C O R E E X T E N S I O N S : H A S H
8/14/2019 Ruby Bits Slides
66/109
difference betwtwo hashes
turn keys into st
options = {user: 'codeschool' , lang: 'fr' }new_options = {user: 'codeschool' , lang: 'fr' , password: 'dunno
{:password=>"dunno"}
options.diff(new_options)
{"user"=>"codeschool", "lang"=>"fr"}
options.stringify_keys
C O R E E X T E N S I O N S : H A S H
8/14/2019 Ruby Bits Slides
67/109
options = { lang: 'fr' , user: 'codeschool'
}
value s f r omt his has h win
options.reverse_merge(defaults)
defaults = { lang: 'en' , country: 'us'
}
lang: 'fr' , user: 'codeschool' ,
country: 'us'
{
}
C O R E E X T E N S I O N S : H A S H
8/14/2019 Ruby Bits Slides
68/109
Unknown key(s): password (ArgumentError)
new_options = {user: 'codeschool' , lang: 'fr' , password: 'dunno
{:user=>"codeschool", :lang=>"fr"}
new_options.except( :password )
new_options.assert_valid_keys( :user , :lang )
remove
throws an exception if the hash contaiany keys besides those listed here
C O R E E X T E N S I O N S : I N T E G E R
8/14/2019 Ruby Bits Slides
69/109
d e t e r mine od d a nde ve n numbe r s
tweets.each_with_index do | tweet , index | puts "#{tweet}" end
def background_class ( index ) return 'white' if index.odd? return 'grey' if index.even? end
I had eggs for breakfast.
@codeschool pwns.Shopping!Bedtime.
I N F L E C T O R
8/14/2019 Ruby Bits Slides
70/109
"1st place!"
"#{ 1.ordinalize} place!"
"2nd place."
"#{ 2.ordinalize} place."
"23rd place."
"#{ 23 .ordinalize} place."
or d inal ize number sto st r in gs
I N F L E C T O R
pl li
8/14/2019 Ruby Bits Slides
71/109
"users"
"user" .pluralize
"woman"
"women" .singularize
"octopi"
"octopus" .pluralize
pl ur al ize and sin gul ar ize str in gs
it knows common speand e ve n s ome uncom
I N F L E C T O R
8/14/2019 Ruby Bits Slides
72/109
"Ruby Bits"
"ruby bits" .titleize
"Account options"
"account_options" .humanize
capitalize ever y w
ad d spaces and capf ir st wor d
8/14/2019 Ruby Bits Slides
73/109
8/14/2019 Ruby Bits Slides
74/109
M O D U L E S
N A M E S PA C EIMAGE UTILS RB
8/14/2019 Ruby Bits Slides
75/109
IMAGE_UTILS .RB
RUN.RB
pollutes glob
potential conmethods wit
def preview
end
transferdefend
( image )
image,( )destination
preview(image)image = user.image
require 'image_utils'
N A M E S PA C EIMAGE UTILS RB
8/14/2019 Ruby Bits Slides
76/109
IMAGE_UTILS .RB
RUN.RB
def preview
end
transferdefend
self.module ImageUtils
end
( image )
image,( )destination
preview(image)
require 'image_utils'
image = user.image
self.
ImageUtils .
M I X I NIMAGE UTILS RB
8/14/2019 Ruby Bits Slides
77/109
IMAGE_UTILS .RB
AVATAR.RB Included as insta
def preview
end
transferdefend
module ImageUtils
end
can accesson objects( )destination
class Image include ImageUtilsend
require 'image_utils'
image = user.imageimage.preview
RUN.RB
A N C E S T O R S
8/14/2019 Ruby Bits Slides
78/109
class Image include ImageUtilsend
Adding modul
ancestors chai
Image .ancestors
Image .included_modules
modules only
[Image, ImageUtils, Object, Kernel, BasicObject]
[ImageUtils, Kernel]
M I X I N S V S C L A S S I N H E R I TA N C E
class Shareableclass Post
8/14/2019 Ruby Bits Slides
79/109
class Shareabledef share_on_facebookend
def share_on_facebookend
def share_on_facebookend
end
end
end
end
class Post
class Image
class Tweet
M I X I N S V S C L A S S I N H E R I TA N C E
< Shareableclass Post class Shareable
8/14/2019 Ruby Bits Slides
80/109
end
def share_on_facebookend
< Shareable
< Shareable
< Shareable
end
end
end
A class can only have o
Some behaviors are notInheritance suggests sp
class Post
class Image
class Tweet
class Shareable
M I X I N S V S C L A S S I N H E R I TA N C E
module Shareableclass Post
8/14/2019 Ruby Bits Slides
81/109
module Shareable
end
def share_on_facebookendend
end
end
include Shareable
include Shareable
include Shareable
class Post
class Image
class Tweet
M I X I N S V S C L A S S I N H E R I TA N C E
class Post
module Shareable
8/14/2019 Ruby Bits Slides
82/109
include Shareable
include Shareable
include Shareable
include Favoritable
include Favoritable
include Favoritable
module Favoritable
end
def add_to_deliciousend
class Post
class Image
class Tweet
module Shareable
end
def share_on_facebookend
end
end
end
M I X I N
8/14/2019 Ruby Bits Slides
83/109
extend Searchable
Included as class methods
module Searchable def find_all_from ( user endend
class Tweet
end
Tweet .find_all_from( '@GreggPollack' )
M I X I N
8/14/2019 Ruby Bits Slides
84/109
image.previewimage = user.image
use include tomethods as instance
use extend to exposemethods as class methods
extend Searchableclass Tweet
end
Tweet .find_all_from( '@GreggPollack' )
class Imageinclude ImageUt
end
M I X I N
8/14/2019 Ruby Bits Slides
85/109
image. extend ( ImageUtils )
image = Image . newimage.previewthe module will not be available in o
an object is extending the mo
image = Image . new
image.preview
NoMethodError: undefined method preview' for #
module ImageUtilsdef preview
endend
class Imageend
H O O K S ! S E L F. I N C L U D E D
8/14/2019 Ruby Bits Slides
86/109
extend ImageUtils :: Cinclude ImageUtils
def fetch_from_twitter ( user )
end
endend
module ClassMethods
module ImageUtils
def preview
end
def transfer ( destination )end
class Image
end
image = user.imageimage.preview
Image .fetch_from_twitter(
H O O K S ! S E L F. I N C L U D E D
8/14/2019 Ruby Bits Slides
87/109
def fetch_from_twitter ( user )end
module ClassMethods
sellf.included is calledwhen a module is incl
in this case, the modulename can be anythingend
end
image = user.imageimage.preview
Image .fetch_from_twitter(
extend ImageUtils :: Cinclude ImageUtils
class Image
end
module ImageUtils
def previewend
def transfer ( destination )end
def self.included ( base )
base. extend ( ClassMethods )end
A C T I V E S U P P O RT: : C O N C E R N
8/14/2019 Ruby Bits Slides
88/109
def self.included ( base )
base. extend ( ClassMethods )base.clean_up
end
module ImageUtils
module ClassMethodsdef fetch_from_twitter ( user )end
def clean_upend
endend
class Imageinclude ImageUtils
end
A C T I V E S U P P O RT: : C O N C E R N
i ' i / 'gem install activesu
8/14/2019 Ruby Bits Slides
89/109
require 'active_support/concern'
includedclean_up
do
extend ActiveSupport :: Concern
} included block is executhe context of the Imagend
ActiveSupport::Concern for a module named Clas
module ImageUtils
module ClassMethodsdef fetch_from_twitter ( user )end
def clean_upend
endend
class Imageinclude ImageUtils
end
A C T I V E S U P P O RT: : C O N C E R N
i l d d ( b )d f lfmodule ImageUtils class Image
8/14/2019 Ruby Bits Slides
90/109
base is Image class
ImageProceson
include ImageProcessinincluded ( base ) def self.
base. extend ( ClassMethods )
calls method onImage class
end
module ImageProcessing
end
def self.included ( base )base.clean_up
end
module ClassMethodsdef clean_up ; end
endend
include ImageUtils
end
A C T I V E S U P P O RT: : C O N C E R N
i l d d ( b )d f lfmodule ImageUtils class Image
8/14/2019 Ruby Bits Slides
91/109
include ImageProcessinincluded ( base ) def self.base. extend ( ClassMethods )
end
module ImageProcessing
end
def self.included ( base )base.clean_up
end
end
end
undefined method er
base is ImageProcessi
module ClassMethodsdef clean_up ; end
end
include ImageUtils
A C T I V E S U P P O RT: : C O N C E R N
incl ded ( base )def selfmodule ImageUtils class Image
8/14/2019 Ruby Bits Slides
92/109
include ImageProcessinincluded ( base ) def self.base. extend ( ClassMethods )
end
module ImageProcessing
end
def self.included ( base )base.clean_up
end
end
end
extend ActiveSupport :: Concern
base is Image class
Dependeproperly
module ClassMethodsdef clean_up ; end
end
include ImageUtils
A C T I V E S U P P O RT: : C O N C E R Nmodule ImageUtils
extend ActiveSupport :: Concern
class Image
8/14/2019 Ruby Bits Slides
93/109
extend ActiveSupport :: Concern
included doclean_up
Dependeproperly
include ImageProcessinend
module ImageProcessing
include ImageUtilsextend ActiveSupport :: Concern
end
end
module ClassMethodsdef clean_up ; end
end
end
8/14/2019 Ruby Bits Slides
94/109
M O D U L E S
8/14/2019 Ruby Bits Slides
95/109
B L O C K S
U S I N G B L O C K S
words = [ 'Had' 'eggs' 'for' 'breakfast ' ]
8/14/2019 Ruby Bits Slides
96/109
words [ Had , eggs , for , breakfast. ]for index in 0..(words.length - 1) puts words[index]
end
words = [ 'Had' , 'eggs' , 'for' , 'breakfast.' ]words.each { | word | puts word }
D E C L A R I N G B L O C K S
braces if the bloc kwords.each { | word | puts word }
8/14/2019 Ruby Bits Slides
97/109
words.each do | word | backward_word = word.reverse puts backward_wordend
braces i is a s in gle l ine
words.each { | word | puts word }
do /end if i t s m ul t i ple l ines
th is is the F I RS Tof t wo con ven t ions!
D E C L A R I N G B L O C K S
do/end if the bloc khigwords.each do | word |
8/14/2019 Ruby Bits Slides
98/109
backward_words = words.map { | word | word.reverse }
do /e DO ES so me th in g
(has a s ide effec t
| | puts wordend
brac j us t i ts r
th is is the S E CO N D
of t wo con ven t ions!
Y I E L D
def call_this_block_twice
8/14/2019 Ruby Bits Slides
99/109
call_this_block_twice { puts "twitter" }
_ _ _ yield yield
end
twittertwitter
call_this_block_twice { puts "tweet" } tweettweet
Y I E L D!
A R G U M E N T S
def call_this_block
8/14/2019 Ruby Bits Slides
100/109
call_this_block { | myarg | puts myarg }
yield "tweet"end
twe
call_this_block { | myarg | puts myarg.upcase } TW
Y I E L D!
R E T U R N VA L U E
def puts_this_block
8/14/2019 Ruby Bits Slides
101/109
puts_this_block { "tweet" }
puts yieldend
tweet
Y I E L D
def call_this_block
8/14/2019 Ruby Bits Slides
102/109
block_result = yield "foo"
puts block_resultend
call_this_block { | arg | arg.reverse }
"oof"
U S I N G B L O C K S
eclass Timeline
8/14/2019 Ruby Bits Slides
103/109
sa med if f e
def list_tweets@user .friends.each do | friend |
friend.tweets.each { | tweet |
endend puts tweet }
def store_tweets@user .friends.each do | friend |
friend.tweets.each { | tweet |end
tweet.cache
endend
}
Y O U R O W N E A C H
class Timeline
8/14/2019 Ruby Bits Slides
104/109
r e - u
timeline = Timeline . new(user)
timeline.each { | tweet | puts tweet }timeline.each { | tweet | tweet.cache }
var y
def each@user .friends.each do | friend |
friend.tweets.each { | tweet |end yield tweet }
endend
E N U M E R A B L E
yo u i m ple men ted h nowmixin
class Timelinedef each
8/14/2019 Ruby Bits Slides
105/109
timeline.sort_by { | tweet | tweet.created_at }timeline.map { | tweet | tweet.status }timeline.find_all { | tweet | tweet.status =~ / \@codeschool/
each , no w m i x in
En u mer able
you instantl y get all these methods, and mor e!
def each
end
endinclude Enumerable
...
E X E C U T E A R O U N D
update_status ( user , tweet )def def get_list ( user , list_namb i
8/14/2019 Ruby Bits Slides
106/109
endend
post(tweet) retrieve_list(list_name)
e ver y th in g b u t the core
lo g ic is d u pl ica ted!
rescue ConnectionError logger.error(e) ensure sign_out(user) endend
begin sign_in(user)
rescue ConnectionError => elogger.error(e)
ensuresign_out(user)
beginsign_in(user)
E X E C U T E A R O U N D
while_signed_in_as ( user ) while_signed_in_as(user) defb i
8/14/2019 Ruby Bits Slides
107/109
end
yield
no w yo u can j us t call the
s in gle me thod w i th a bloc k!
tweets = while_signed_in_as(use
post(tweet)end
retrieve_list(list_name)end
rescue ConnectionError => elogger.error(e)
ensuresign_out(user)
end
sign_in(user)begin
E X E C U T E A R O U N D
def while_signed_in_as ( user )i i ( )
8/14/2019 Ruby Bits Slides
108/109
no need f or be g in /end w i th in a me thod!
C O M B O X 2 !
rescue ConnectionError => elogger.error(e)ensure
sign_out(user)
sign_in(user)
end
yield
8/14/2019 Ruby Bits Slides
109/109
B L O C K S