RUBY 2.X
Thursday, October 10, 13
2012
Thursday, October 10, 13
RUBY
+ berljivost
+ površinska enostavnost
+ polno objektni jezik
+ funkcijsko programiranje
+ metaprogramiranje
+ ekosist...
(0..10).each do |x|
puts "The number is: #{x}"
end
<?php
for ($x=0; $x<=10; $x++)
{
echo "The number is: $x";
}
?>
for x i...
(0..10).each do |x|
puts "The number is: #{x}"
end
<?php
for ($x=0; $x<=10; $x++)
{
echo "The number is: $x";
}
?>
for x i...
(0..10).each do |x|
puts "The number is: #{x}"
end
<?php
for ($x=0; $x<=10; $x++)
{
echo "The number is: $x";
}
?>
for x i...
(0..10).each do |x|
puts "The number is: #{x}"
end
<?php
for ($x=0; $x<=10; $x++)
{
echo "The number is: $x";
}
?>
for x i...
(0..10).each do |x|
puts "The number is: #{x}"
end
<?php
for ($x=0; $x<=10; $x++)
{
echo "The number is: $x";
}
?>
for x i...
(0..10).each do |x|
puts "The number is: #{x}"
end
<?php
for ($x=0; $x<=10; $x++)
{
echo "The number is: $x";
}
?>
for x i...
RUBY 2.0
Thursday, October 10, 13
KEYWORD ARGUMENTI
# Ruby < 2
def run(options = {})
options.reverse_merge!(
opt1: "default"
)
raise ArgumentError unless op...
MODULE#PREPEND
Thursday, October 10, 13
class Bar
def hello
puts 1
end
end
Bar.new.hello
Bar.ancestors
๏ BasicObject
๏ Kernel
๏ Object
๏ Bar
Thursday, October 10,...
class Foo
def hello
puts 'hello'
end
end
class Bar < Foo
def hello
puts 1
super
end
end
Bar.new.hello
Bar.ancestors
๏ Basi...
module FooBar
def hello
puts 2
super
end
end
class Foo
def hello
puts 'hello'
end
end
class Bar < Foo
include FooBar
def h...
module FooBar
def hello
puts 2
super
end
end
class Foo
def hello
puts 'hello'
end
end
class Bar < Foo
include FooBar
def h...
module FooBar
def hello
puts 2
super
end
end
class Foo
def hello
puts 'hello'
end
end
class Bar < Foo
prepend FooBar
def h...
module FooBar
def hello
puts 2
super
end
end
class Foo
def hello
puts 'hello'
end
end
class Bar < Foo
prepend FooBar
def h...
LAZY ENUMERATIONS
Thursday, October 10, 13
ENUMERATIONS
[1, 2, 3, 4]
.map { |i| i * 2 } # => [2, 4, 6, 8]
.take(2) # => [2, 4]
.reduce(&:+) # => 6
Thursday, October ...
LAZY
[1, 2, 3, 4]
.lazy # => #<Enumerator::Lazy: [1, 2, 3, 4]>
.map { |i| i * 2 } # => #<Enumerator::Lazy: [1, 2, 3,
4]>:m...
LAZY
(1..Float::INFINITY)
.lazy
.map { |i| i * 2 }
.take(2)
.reduce(&:+)
Thursday, October 10, 13
GENERATIONAL GARBAGE
COLLECTOR
If you care about GC, just use JRuby.
Thursday, October 10, 13
GENERATIONAL GARBAGE
COLLECTOR
If you care about GC, just use JRuby.
switch to JRuby
Thursday, October 10, 13
RUBY 2.0: REFINEMENTS
Meh.
Thursday, October 10, 13
RUBY 2.1: REFINEMENTS
module BalkanString
refine String do
def debalkanize
ActiveSupport::Inflector.transliterate(self)
en...
RUBY ON RAILS
Thursday, October 10, 13
Django
146,869 LOC
Rails
162,084 LOC
CakePHP
147,738 LOC
Lines of code
Thursday, October 10, 13
100% MODULAREN
Thursday, October 10, 13
Rails
‣lepilo
‣Model
‣View
‣Controller
Thursday, October 10, 13
Rails
‣lepilo
‣Model
‣View
‣Controller
Thursday, October 10, 13
Rails
‣railties 16,017 LOC
‣activesupport 25,710 LOC
‣Model
‣View
‣Controller
Thursday, October 10, 13
Rails
‣railties
‣activesupport
‣Model
‣View
‣Controller
Thursday, October 10, 13
Rails
‣railties
‣activesupport
‣activemodel 5,694 LOC
‣activerecord 53,435 LOC
‣View
‣Controller
Thursday, October 10, 13
Rails
‣railties
‣activesupport
‣activemodel
‣activerecord
‣View
‣Controller
Thursday, October 10, 13
Rails
‣railties
‣activesupport
‣activemodel
‣activerecord
‣actionview 22,501 LOC
‣Controller
Thursday, October 10, 13
Rails
‣railties
‣activesupport
‣activemodel
‣activerecord
‣actionview
‣Controller
Thursday, October 10, 13
Rails
‣railties
‣activesupport
‣activemodel
‣activerecord
‣actionview
‣actionpack 35,538 LOC
Thursday, October 10, 13
Rails
‣railties
‣activesupport
‣activemodel
‣activerecord
‣actionview
‣actionpack
Thursday, October 10, 13
DEPLOY
Unicorn
Rainbows!
Thursday, October 10, 13
RAILS 4
Thursday, October 10, 13
TURBOLINKS
Video (57:10)
Rails Conf 2013 Patterns of Basecamp's Application
Architecture by David Heinemeier Hansson
http:...
THREAD SAFE
JBoss, 200 threads, OK
Thursday, October 10, 13
DON’T JUSTTRY,TRY!
# Rails 3
[10].try(:count) # => 1
5.try(:count) # NoMethodError
nil.try(:count) # => nil
# Rails 4
5.tr...
ACTIONCONTROLLER::LIVE
class MyController < ActionController::Base
include ActionController::Live
def stream
response.head...
POSTGRESQL
Array
Thursday, October 10, 13
POSTGRESQL ARRAY
class CreateDocuments < ActiveRecord::Migration
def change
create_table :documents do |t|
t.string :title...
POSTGRESQL ARRAY
Document.create(title: "PostgreSQL", tags: ["pg","rails"])
Document.where("'pg' = ANY (tags)")
Thursday, ...
POSTGRESQL
hstore (Hash/Dictionary)
Thursday, October 10, 13
POSTGRESQL HSTORE
class AddHstoreExtension < ActiveRecord::Migration
def up
execute 'CREATE EXTENSION hstore'
end
def down...
POSTGRESQL HSTORE
class Comic < ActiveRecord::Base
end
Comic.create(properties: { issued: 1.year.ago })
Comic.where("prope...
POSTGRESQL HSTORE
class Comic < ActiveRecord::Base
store_accessor :properties, :issued
end
Comic.create(issued: 1.year.ago...
ACTIVERECORD
In Rails 4
Thursday, October 10, 13
SCOPES
class User < ActiveRecord::Base
# Rails 3
scope :newest, where("created_at > ?", 1.week.ago)
# Rails 4
scope :newes...
WHERE.NOT
# Rails 3
User.where('role != ?', 'admin')
User.where('nickname IS NOT NULL')
# Rails 4
User.where.not(role: 'ad...
MIGRACIJE PREJ
class ChangeProductsPrice < ActiveRecord::Migration
def up
change_table :products do |t|
t.change :price, :...
MIGRACIJE
class ChangeProductsPrice < ActiveRecord::Migration
def change
reversible do |dir|
change_table :products do |t|...
NONE RELATION
class User < ActiveRecord::Base
scope :with_role, ->(role) {
if User.role_valid? role
where(role: role)
else...
STRONG PARAMETERS
Thursday, October 10, 13
PROBLEM
• User
• name
• is_admin
Thursday, October 10, 13
RAILS 3
class User < ActiveRecord::Base
attr_accessible :name
end
# controller
user.update_attributes(params[:user])
# adm...
RAILS 3
class User < ActiveRecord::Base
attr_accessible :name
end
# controller
user.update_attributes(params[:user])
v čem...
RAILS 3
class User < ActiveRecord::Base
attr_accessible :name
end
# controller
user.update_attributes(params[:user])
user....
STRONG PARAMETERS
class User < ActiveRecord::Base
end
# controller
def user_params
params.require(:user).permit(:name)
end...
CACHING
• avtomatski expire pri spremembi modela
• avtomatski expire pri spremembi viewa
• russian doll (nested) caching
•...
ACTIVESUPPORT::CONCERN
module Commentable
extend ActiveSupport::Concern
included do
has_many :comments
end
def has_comment...
THE END
Thursday, October 10, 13
Upcoming SlideShare
Loading in …5
×

D-Talk: What's awesome about Ruby 2.x and Rails 4

1,222 views

Published on

D-Talk by Jan Berdajs

Published in: Technology
0 Comments
4 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
1,222
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
9
Comments
0
Likes
4
Embeds 0
No embeds

No notes for slide

D-Talk: What's awesome about Ruby 2.x and Rails 4

  1. 1. RUBY 2.X Thursday, October 10, 13
  2. 2. 2012 Thursday, October 10, 13
  3. 3. RUBY + berljivost + površinska enostavnost + polno objektni jezik + funkcijsko programiranje + metaprogramiranje + ekosistem + RubyGems - metaprogramiranje - hitrost vs. Scala, Java, C - znanost (SciPy) Thursday, October 10, 13
  4. 4. (0..10).each do |x| puts "The number is: #{x}" end <?php for ($x=0; $x<=10; $x++) { echo "The number is: $x"; } ?> for x in range(0, 11): print 'The number is: %d' % (x) Ruby PHP Python Thursday, October 10, 13
  5. 5. (0..10).each do |x| puts "The number is: #{x}" end <?php for ($x=0; $x<=10; $x++) { echo "The number is: $x"; } ?> for x in range(0, 11): print 'The number is: %d' % (x) Ruby PHP Python for x in 0..10 puts 'The number is: %d' % [x] end Thursday, October 10, 13
  6. 6. (0..10).each do |x| puts "The number is: #{x}" end <?php for ($x=0; $x<=10; $x++) { echo "The number is: $x"; } ?> for x in range(0, 11): print 'The number is: %d' % (x) Ruby PHP Python for x in 0..10 puts 'The number is: %d' % [x] end 0.upto(10).each { |x| printf('The number is: %d', x) } Thursday, October 10, 13
  7. 7. (0..10).each do |x| puts "The number is: #{x}" end <?php for ($x=0; $x<=10; $x++) { echo "The number is: $x"; } ?> for x in range(0, 11): print 'The number is: %d' % (x) Ruby PHP Python for x in 0..10 puts 'The number is: %d' % [x] end 0.upto(10).each { |x| printf('The number is: %d', x) } 11.times do |x| puts "The number is: #{x}" end Thursday, October 10, 13
  8. 8. (0..10).each do |x| puts "The number is: #{x}" end <?php for ($x=0; $x<=10; $x++) { echo "The number is: $x"; } ?> for x in range(0, 11): print 'The number is: %d' % (x) Ruby PHP Python for x in 0..10 puts 'The number is: %d' % [x] end 0.upto(10).each { |x| printf('The number is: %d', x) } 11.times do |x| puts "The number is: #{x}" end puts (0..10).map{|x| "The number is: #{x}"} Thursday, October 10, 13
  9. 9. (0..10).each do |x| puts "The number is: #{x}" end <?php for ($x=0; $x<=10; $x++) { echo "The number is: $x"; } ?> for x in range(0, 11): print 'The number is: %d' % (x) Ruby PHP Python for x in 0..10 puts 'The number is: %d' % [x] end 0.upto(10).each { |x| printf('The number is: %d', x) } 11.times do |x| puts "The number is: #{x}" end puts (0..10).map{|x| "The number is: #{x}"} puts ("The number is Nn" * 11).gsub('N').with_index{|_,i| i} Thursday, October 10, 13
  10. 10. RUBY 2.0 Thursday, October 10, 13
  11. 11. KEYWORD ARGUMENTI # Ruby < 2 def run(options = {}) options.reverse_merge!( opt1: "default" ) raise ArgumentError unless options.keys.in?([:opt1, :opt2]) options[:opt1] end # Ruby 2 def run(opt1: "default", opt2: nil) opt1 end run(opt2: "x") run(opt2: "x", opt3: "y") # ArgumentError def run(opt1: "default", opt2: nil, **options) opt1 end run(opt2: "x", opt3: "y") Thursday, October 10, 13
  12. 12. MODULE#PREPEND Thursday, October 10, 13
  13. 13. class Bar def hello puts 1 end end Bar.new.hello Bar.ancestors ๏ BasicObject ๏ Kernel ๏ Object ๏ Bar Thursday, October 10, 13
  14. 14. class Foo def hello puts 'hello' end end class Bar < Foo def hello puts 1 super end end Bar.new.hello Bar.ancestors ๏ BasicObject ๏ Kernel ๏ Object ๏ Foo ๏ Bar Thursday, October 10, 13
  15. 15. module FooBar def hello puts 2 super end end class Foo def hello puts 'hello' end end class Bar < Foo include FooBar def hello puts 1 super end end Bar.new.hello Bar.ancestors ๏ BasicObject ๏ Kernel ๏ Object ๏ Foo ๏ FooBar ๏ Bar Thursday, October 10, 13
  16. 16. module FooBar def hello puts 2 super end end class Foo def hello puts 'hello' end end class Bar < Foo include FooBar def hello puts 1 super end end Bar.new.hello Bar.ancestors ๏ BasicObject ๏ Kernel ๏ Object ๏ Foo ๏ FooBar ๏ Bar 1 2 hello Thursday, October 10, 13
  17. 17. module FooBar def hello puts 2 super end end class Foo def hello puts 'hello' end end class Bar < Foo prepend FooBar def hello puts 1 super end end Bar.new.hello Bar.ancestors ๏ BasicObject ๏ Kernel ๏ Object ๏ Foo ๏ Bar ๏ FooBar Thursday, October 10, 13
  18. 18. module FooBar def hello puts 2 super end end class Foo def hello puts 'hello' end end class Bar < Foo prepend FooBar def hello puts 1 super end end Bar.new.hello Bar.ancestors ๏ BasicObject ๏ Kernel ๏ Object ๏ Foo ๏ Bar ๏ FooBar 2 1 hello Thursday, October 10, 13
  19. 19. LAZY ENUMERATIONS Thursday, October 10, 13
  20. 20. ENUMERATIONS [1, 2, 3, 4] .map { |i| i * 2 } # => [2, 4, 6, 8] .take(2) # => [2, 4] .reduce(&:+) # => 6 Thursday, October 10, 13
  21. 21. LAZY [1, 2, 3, 4] .lazy # => #<Enumerator::Lazy: [1, 2, 3, 4]> .map { |i| i * 2 } # => #<Enumerator::Lazy: [1, 2, 3, 4]>:map> .take(2) # => #<Enumerator::Lazy: #<Enumerator::Lazy: [1, 2, 3, 4]>:map>:take(2)> .reduce(&:+) # => 6 Thursday, October 10, 13
  22. 22. LAZY (1..Float::INFINITY) .lazy .map { |i| i * 2 } .take(2) .reduce(&:+) Thursday, October 10, 13
  23. 23. GENERATIONAL GARBAGE COLLECTOR If you care about GC, just use JRuby. Thursday, October 10, 13
  24. 24. GENERATIONAL GARBAGE COLLECTOR If you care about GC, just use JRuby. switch to JRuby Thursday, October 10, 13
  25. 25. RUBY 2.0: REFINEMENTS Meh. Thursday, October 10, 13
  26. 26. RUBY 2.1: REFINEMENTS module BalkanString refine String do def debalkanize ActiveSupport::Inflector.transliterate(self) end end end class User < ActiveRecord::Base using BalkanString def name @name.debalkanize if @name end end "test".debalkanize # NoMethodError Thursday, October 10, 13
  27. 27. RUBY ON RAILS Thursday, October 10, 13
  28. 28. Django 146,869 LOC Rails 162,084 LOC CakePHP 147,738 LOC Lines of code Thursday, October 10, 13
  29. 29. 100% MODULAREN Thursday, October 10, 13
  30. 30. Rails ‣lepilo ‣Model ‣View ‣Controller Thursday, October 10, 13
  31. 31. Rails ‣lepilo ‣Model ‣View ‣Controller Thursday, October 10, 13
  32. 32. Rails ‣railties 16,017 LOC ‣activesupport 25,710 LOC ‣Model ‣View ‣Controller Thursday, October 10, 13
  33. 33. Rails ‣railties ‣activesupport ‣Model ‣View ‣Controller Thursday, October 10, 13
  34. 34. Rails ‣railties ‣activesupport ‣activemodel 5,694 LOC ‣activerecord 53,435 LOC ‣View ‣Controller Thursday, October 10, 13
  35. 35. Rails ‣railties ‣activesupport ‣activemodel ‣activerecord ‣View ‣Controller Thursday, October 10, 13
  36. 36. Rails ‣railties ‣activesupport ‣activemodel ‣activerecord ‣actionview 22,501 LOC ‣Controller Thursday, October 10, 13
  37. 37. Rails ‣railties ‣activesupport ‣activemodel ‣activerecord ‣actionview ‣Controller Thursday, October 10, 13
  38. 38. Rails ‣railties ‣activesupport ‣activemodel ‣activerecord ‣actionview ‣actionpack 35,538 LOC Thursday, October 10, 13
  39. 39. Rails ‣railties ‣activesupport ‣activemodel ‣activerecord ‣actionview ‣actionpack Thursday, October 10, 13
  40. 40. DEPLOY Unicorn Rainbows! Thursday, October 10, 13
  41. 41. RAILS 4 Thursday, October 10, 13
  42. 42. TURBOLINKS Video (57:10) Rails Conf 2013 Patterns of Basecamp's Application Architecture by David Heinemeier Hansson http://www.youtube.com/watch?v=yhseQP52yIY Thursday, October 10, 13
  43. 43. THREAD SAFE JBoss, 200 threads, OK Thursday, October 10, 13
  44. 44. DON’T JUSTTRY,TRY! # Rails 3 [10].try(:count) # => 1 5.try(:count) # NoMethodError nil.try(:count) # => nil # Rails 4 5.try(:count) # => nil 5.try!(:count) # NoMethodError nil.try(:count) #=> nil nil.try!(:count) #=> nil Thursday, October 10, 13
  45. 45. ACTIONCONTROLLER::LIVE class MyController < ActionController::Base include ActionController::Live def stream response.headers['Content-Type'] = 'text/event-stream' 100.times { response.stream.write "hello worldn" sleep 1 } ensure response.stream.close end end avtomatsko naredi thread Thursday, October 10, 13
  46. 46. POSTGRESQL Array Thursday, October 10, 13
  47. 47. POSTGRESQL ARRAY class CreateDocuments < ActiveRecord::Migration def change create_table :documents do |t| t.string :title t.string :tags, array: true, default: [] t.timestamps end end end Thursday, October 10, 13
  48. 48. POSTGRESQL ARRAY Document.create(title: "PostgreSQL", tags: ["pg","rails"]) Document.where("'pg' = ANY (tags)") Thursday, October 10, 13
  49. 49. POSTGRESQL hstore (Hash/Dictionary) Thursday, October 10, 13
  50. 50. POSTGRESQL HSTORE class AddHstoreExtension < ActiveRecord::Migration def up execute 'CREATE EXTENSION hstore' end def down execute 'DROP EXTENSION hstore' end end class AddPropertiesToComics < ActiveRecord::Migration def change add_column :comics, :properties, :hstore end end Thursday, October 10, 13
  51. 51. POSTGRESQL HSTORE class Comic < ActiveRecord::Base end Comic.create(properties: { issued: 1.year.ago }) Comic.where("properties -> 'issued' > ?", 2.years.ago) Thursday, October 10, 13
  52. 52. POSTGRESQL HSTORE class Comic < ActiveRecord::Base store_accessor :properties, :issued end Comic.create(issued: 1.year.ago) Comic.where("properties -> 'issued' > ?", 2.years.ago) Ali sploh rabiš hstore v tem primeru? Thursday, October 10, 13
  53. 53. ACTIVERECORD In Rails 4 Thursday, October 10, 13
  54. 54. SCOPES class User < ActiveRecord::Base # Rails 3 scope :newest, where("created_at > ?", 1.week.ago) # Rails 4 scope :newest, -> { where("created_at > ?", 1.week.ago) } end Thursday, October 10, 13
  55. 55. WHERE.NOT # Rails 3 User.where('role != ?', 'admin') User.where('nickname IS NOT NULL') # Rails 4 User.where.not(role: 'admin') User.where.not(nickname: nil) Thursday, October 10, 13
  56. 56. MIGRACIJE PREJ class ChangeProductsPrice < ActiveRecord::Migration def up change_table :products do |t| t.change :price, :string end end def down change_table :products do |t| t.change :price, :integer end end end Thursday, October 10, 13
  57. 57. MIGRACIJE class ChangeProductsPrice < ActiveRecord::Migration def change reversible do |dir| change_table :products do |t| dir.up { t.change :price, :string } dir.down { t.change :price, :integer } end end end end Thursday, October 10, 13
  58. 58. NONE RELATION class User < ActiveRecord::Base scope :with_role, ->(role) { if User.role_valid? role where(role: role) else none end } end User.with_role(params[:role]).where.not(nick: nil) Thursday, October 10, 13
  59. 59. STRONG PARAMETERS Thursday, October 10, 13
  60. 60. PROBLEM • User • name • is_admin Thursday, October 10, 13
  61. 61. RAILS 3 class User < ActiveRecord::Base attr_accessible :name end # controller user.update_attributes(params[:user]) # admin user.update_attributes(is_admin: true) # :-( user.is_admin = true user.save Thursday, October 10, 13
  62. 62. RAILS 3 class User < ActiveRecord::Base attr_accessible :name end # controller user.update_attributes(params[:user]) v čem je v resnici problem? Thursday, October 10, 13
  63. 63. RAILS 3 class User < ActiveRecord::Base attr_accessible :name end # controller user.update_attributes(params[:user]) user.update_attributes(is_admin: true) # :-( non-sanitized user input Thursday, October 10, 13
  64. 64. STRONG PARAMETERS class User < ActiveRecord::Base end # controller def user_params params.require(:user).permit(:name) end user.update_attributes(user_params) user.update_attributes(params[:user]) # error: Unpermitted parameters user.update_attributes(is_admin: true) # OK :-) Thursday, October 10, 13
  65. 65. CACHING • avtomatski expire pri spremembi modela • avtomatski expire pri spremembi viewa • russian doll (nested) caching • Rails Conf 2013 Patterns of Basecamp's Application Architecture by David Heinemeier Hansson • http://www.youtube.com/watch?v=yhseQP52yIY Thursday, October 10, 13
  66. 66. ACTIVESUPPORT::CONCERN module Commentable extend ActiveSupport::Concern included do has_many :comments end def has_comments? !comments.empty? end module ClassMethods def comments_count joins(:comments) .references(:comments) .pluck("COUNT(comments.id)") end end end class Post < ActiveRecord::Base include Commentable end User.posts.comment_count Post.first.comments Post.first.has_comments? Rails 4 ima direktorij za concerne. Whatever. Thursday, October 10, 13
  67. 67. THE END Thursday, October 10, 13

×