SlideShare una empresa de Scribd logo
1 de 97
Descargar para leer sin conexión
Refatorando Código
       Ruby


@caike
http://caikesouza.com
caike@envylabs.com
www.envylabs.com
Métodos
 Ágeis
Testes
(Anti-)Patterns
Software
Craftsmanship
"Any fool can write code that
   a computer can understand.
Good programmers write code that
    humans can understand"

          (Martin Fowler)
Refatorar é ...
Limpar a casa sem
 mudar a fachada
Algumas razões
Design
Responder
a mudanças
Entregas
Constantes
Waterfall




Jan   Feb   Mar    Apr     May     Jun           Jul

             Cost of Maintenance         Extreme Programming Explained: Embrace Change
                                                     Addison Wesley, 2000
XP




Jan   Feb   Mar    Apr     May     Jun           Jul

             Cost of Maintenance         Extreme Programming Explained: Embrace Change
                                                     Addison Wesley, 2000
Quando ?
novas features
bugs
Débito Técnico
Code Reviews
“The great thing about programming is
  pretty much everyone's code is shit.
Writing software is hard, so it's no problem
      finding dogs in someone's stuff”

                 (Zed Shaw)
exemplos.rb
managers = []

employees.each do |e|
  managers << e if e.is_manager?
end
managers = []

employees.each do |e|
  managers << e if e.is_manager?
end
Replace Loop with
 Closure Method
managers = []

employees.each do |e|
  managers << e if e.is_manager?
end
managers = employees.
  select { |e| e.is_manager? }
class Movie
  def initialize(stars)
    @stars = stars
  end

  def recommended?
    ((@stars > 5) ? 8 : 1) >= 8
  end
end
class Movie
  def initialize(stars)
    @stars = stars
  end

  def recommended?
    ((@stars > 5) ? 8 : 1) >= 8
  end
end
Introduce Explaining
      Variable
class Movie
  def initialize(stars)
    @stars = stars
  end

  def recommended?
    ((@stars > 5) ? 8 : 1) >= 8
  end
end
class Movie
  def initialize(stars)
    @stars = stars
  end

  def recommended?
    rating = (@stars > 5) ? 8 : 1
    rating >= 8
  end
end
class Movie
  def initialize(stars)
    @stars = stars
  end

  def recommended?
    rating = (@stars > 5) ? 8 : 1
    rating >= 8
  end
end
Replace Temp
With Query
class Movie
  def initialize(stars)
    @stars = stars
  end

  def recommended?
    rating = (@stars > 5) ? 8 : 1
    rating >= 8
  end
end
class Movie
  def initialize(stars)
    @stars = stars
  end

  def recommended?
    rating >= 8
  end

  def rating
    (@stars > 5) ? 8 : 1
  end
end
OMG OMG OMG OMG OMG
class Movie

  def recommended?
    rating >= 8
  end

  def rating
    (@stars > 5) ? 8 : 1
  end
end
class Movie

  def recommended?
    rating >= 8
  end

  def rating
    more_than_five_stars? ? 8 : 1
  end

  def more_than_five_stars?
    @stars > 5
  end
end
Inline Method
class Movie
  def initialize...end
  def recommended?
    rating >= 8
  end

  def rating
    more_than_five_stars? ? 8 : 1
  end

  def more_than_five_stars?
    @stars > 5
  end
end
class Movie
  def initialize...end
  def recommended?
    rating >= 8
  end

  def rating
    @stars > 5 ? 8 : 1
  end




end
mock = mock('user')
expectation = mock.expects(:find)
expectation.with("1")
expectation.returns([])
mock = mock('user')
expectation = mock.expects(:find)
expectation.with("1")
expectation.returns([])
Replace Temp
 With Chain
mock = mock('user')
expectation = mock.expects(:find)
expectation.with("1")
expectation.returns([])
mock = mock('user')
mock.expects(:find).with("1").
      returns([])
Command
  vs.
 Query
def expects
  ...
  self
end

def with
  ...
  self
end

def returns
  ...
  self
end
def charge(amount, card_number)
  begin
    conn = CC_Charger_Server.connect(...)
    conn.send(amount, card_number)
  rescue IOError => e
    Logger.log "Error: #{e}"
    return nil
  ensure
    conn.close
  end
end
def charge(amount, card_number)
  begin
    conn = CC_Charger_Server.connect(...)
    conn.send(amount, card_number)
  rescue IOError => e
    Logger.log "Error: #{e}"
    return nil
  ensure
    conn.close
  end
end
Extract Surrounding
      Method
def charge(amount, ccnumber)
  begin
    conn = CC_Charger_Server.connect(...)
    conn.send(amount, card_number)
  rescue IOError => e
    Logger.log "Error: #{e}"
    return nil
  ensure
    conn.close
  end
end
def charge(amount, card_number)
  connect do |conn|
    conn.send(amount, card_number)
  end
end
def connect
  begin
    conn = CC_Charger_Server.connect(...)
    yield conn
  rescue IOError => e
    Logger.log "Error: #{e}"
    return nil
  ensure
    conn.close
  end
end
def body_fat_percentage(name,
  age, height, weight, metric_system)
  ...
end
body_fat_percentage("fred", 30, 1.82, 90, 1)
body_fat_percentage("joe", 32, 6, 220, 2)
body_fat_percentage("fred", 30, 1.82, 90, 1)
body_fat_percentage("joe", 32, 6, 220, 2)
Introduce Named Parameter
body_fat_percentage("fred", 30, 1.82, 90, 1)
body_fat_percentage("joe", 32, 6, 220, 2)
body_fat_percentage("fred", :age => 30,
  :height => 1.82, :weight => 90,
  MetricSystem::METERS_KG)

body_fat_percentage("joe", :age => 32,
  :height => 6, :weight => 220,
  MetricSystem::FEET_LB)
def body_fat_percentage(name,
  age, height, weight, metric_system)
  ...
end
def   body_fat_percentage(name, params={})
  #   params[:age]
  #   params[:height]
  #   params[:weight]
  #   params[:metric_system]
end
user.posts.paginate(:page => params[:page],
    :per_page => params[:per_page] || 15)
user.posts.paginate(:page => params[:page],
    :per_page => params[:per_page] || 15)
Replace Magic Number
with Symbolic Constant
user.posts.paginate(:page => params[:page],
    :per_page => params[:per_page] || 15)
CONTACTS_PER_PAGE = 15

user.posts.paginate(:page => params[:page],
    :per_page => params[:per_page] ||
CONTACTS_PER_PAGE)
class MountainBike
  def price
    ...
  end
end

MountainBike.new(:type => :rigid, ...)
MountainBike.new(:type => :front_suspension, ...)
MountainBike.new(:type => :full_suspension, ...)
def price
  if @type_code == :rigid
      (1 + @comission) * @base_price
  end
  if @type_code == :font_suspension
    (1 + @comission) * @base_price +
    @front_suspension_price
  end
  if @type_code == :full_suspension
    (1 + @comission) * @base_price+
    @front_suspension_price +
    @rear_suspension_price
  end




end
def price
  if @type_code == :rigid
      (1 + @comission) * @base_price
  end
  if @type_code == :font_suspension
    (1 + @comission) * @base_price +
    @front_suspension_price
  end
  if @type_code == :full_suspension
    (1 + @comission) * @base_price+
    @front_suspension_price +
    @rear_suspension_price
  end
  if @type_code == :ultra_suspension
      ...
  end
end
CLOSED for modification
  OPEN for extension
Replace Conditional
With Polymorphism
class MountainBike
  def price
    ...
  end
end
module MountainBike
  def price
    ...
  end
end
class RigidMountainBike
  include MountainBike
end

class FrontSuspensionMountainBike
  include MountainBike
end

class FullSuspensionMountainBike
  include MountainBike
end
RigidMountainBike.new(:type => :rigid, ...)

FrontSuspensionMountainBike.new(:type =>
:front_suspension, ...)

FullSuspensionMountainBike.new(:type =>
 :full_suspension, ...)
class RigidMountainBike
  include MountainBike

  def price
    (1 + @comission) * @base_price
  end
end
class FrontSuspensionMountainBike
  include MountainBike
  def price
    (1 + @comission) * @base_price +
    @front_suspension_price
  end
end

class FullSuspensionMountainBike
  include MountainBike
  def price
    (1 + @comission) * @base_price +
    @front_suspension_price +
    @rear_suspension_price
  end
end
def price
  if @type_code == :rigid
    raise "should not be called"
  end
  if @type_code == :font_suspension
    (1 + @comission) * @base_price +
    @front_suspension_price
  end
  if @type_code == :full_suspension
    (1 + @comission) * @base_price+
    @front_suspension_price +
    @rear_suspension_price
  end
end
def price
  if @type_code == :rigid
    raise "should not be called"
  end
  if @type_code == :font_suspension
    raise "should not be called"
  end
  if @type_code == :full_suspension
    raise "should not be called"
  end
end
def price
  if @type_code == :rigid
    raise "should not be called"
  end
  if @type_code == :font_suspension
    raise "should not be called"
  end
  if @type_code == :full_suspension
    raise "should not be called"
  end
end
class RigidMountainBike
  include MountainBike
end

class FrontSuspensionMountainBike
  include MountainBike
end

class FullSuspensionMountainBike
  include MountainBike
end
Coding Dojo




  http://orlandodojo.org/
  http://dojorio.org/
Obrigado!
           http://www.flickr.com/photos/eurleif/255241547/
           http://www.flickr.com/photos/dhammza/91435718/
           http://www.flickr.com/photos/krash0387
           http://www.flickr.com/photos/benfrantzdale/208672143/
           http://www.flickr.com/photos/improveit/1574023621/
           http://www.flickr.com/photos/aaroncoyle/972403508
           http://www.flickr.com/photos/talios/3726484920
           http://www.flickr.com/photos/moow/3412079622
           http://www.flickr.com/photos/highwayoflife/2699887178/


@caike
http://caikesouza.com
http://smallactsmanifesto.org

Más contenido relacionado

Similar a Refactoring Ruby Code

How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everythingnoelrap
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescriptDavid Furber
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonPython Ireland
 
Polyglot Programming in the JVM
Polyglot Programming in the JVMPolyglot Programming in the JVM
Polyglot Programming in the JVMAndres Almiray
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Codemotion
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Coxlachie
 
tictactoe groovy
tictactoe groovytictactoe groovy
tictactoe groovyPaul King
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record.toster
 
How to write maintainable code without tests
How to write maintainable code without testsHow to write maintainable code without tests
How to write maintainable code without testsJuti Noppornpitak
 
November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2Kacper Gunia
 
Vision academy classes bcs_bca_bba_sybba_php
Vision academy  classes bcs_bca_bba_sybba_phpVision academy  classes bcs_bca_bba_sybba_php
Vision academy classes bcs_bca_bba_sybba_phpsachin892777
 
RSpock Testing Framework for Ruby
RSpock Testing Framework for RubyRSpock Testing Framework for Ruby
RSpock Testing Framework for RubyBrice Argenson
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick touraztack
 
Intermediate SQL with Ecto - LoneStar ElixirConf 2018
Intermediate SQL with Ecto - LoneStar ElixirConf 2018Intermediate SQL with Ecto - LoneStar ElixirConf 2018
Intermediate SQL with Ecto - LoneStar ElixirConf 2018wreckoning
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTPMustafa TURAN
 

Similar a Refactoring Ruby Code (20)

Refactoring
RefactoringRefactoring
Refactoring
 
Refactoring
RefactoringRefactoring
Refactoring
 
Language supports it
Language supports itLanguage supports it
Language supports it
 
Ruby tricks2
Ruby tricks2Ruby tricks2
Ruby tricks2
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
How To Test Everything
How To Test EverythingHow To Test Everything
How To Test Everything
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
Object Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in PythonObject Orientation vs. Functional Programming in Python
Object Orientation vs. Functional Programming in Python
 
Polyglot Programming in the JVM
Polyglot Programming in the JVMPolyglot Programming in the JVM
Polyglot Programming in the JVM
 
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017 Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
Davide Cerbo - Kotlin: forse è la volta buona - Codemotion Milan 2017
 
Blocks by Lachs Cox
Blocks by Lachs CoxBlocks by Lachs Cox
Blocks by Lachs Cox
 
tictactoe groovy
tictactoe groovytictactoe groovy
tictactoe groovy
 
Attributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active recordAttributes Unwrapped: Lessons under the surface of active record
Attributes Unwrapped: Lessons under the surface of active record
 
How to write maintainable code without tests
How to write maintainable code without testsHow to write maintainable code without tests
How to write maintainable code without tests
 
November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2November Camp - Spec BDD with PHPSpec 2
November Camp - Spec BDD with PHPSpec 2
 
Vision academy classes bcs_bca_bba_sybba_php
Vision academy  classes bcs_bca_bba_sybba_phpVision academy  classes bcs_bca_bba_sybba_php
Vision academy classes bcs_bca_bba_sybba_php
 
RSpock Testing Framework for Ruby
RSpock Testing Framework for RubyRSpock Testing Framework for Ruby
RSpock Testing Framework for Ruby
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Intermediate SQL with Ecto - LoneStar ElixirConf 2018
Intermediate SQL with Ecto - LoneStar ElixirConf 2018Intermediate SQL with Ecto - LoneStar ElixirConf 2018
Intermediate SQL with Ecto - LoneStar ElixirConf 2018
 
Re-Design with Elixir/OTP
Re-Design with Elixir/OTPRe-Design with Elixir/OTP
Re-Design with Elixir/OTP
 

Último

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Principled Technologies
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?Igalia
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingEdi Saputra
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonAnna Loughnan Colquhoun
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 

Último (20)

Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
Deploy with confidence: VMware Cloud Foundation 5.1 on next gen Dell PowerEdg...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost SavingRepurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
Repurposing LNG terminals for Hydrogen Ammonia: Feasibility and Cost Saving
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Data Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt RobisonData Cloud, More than a CDP by Matt Robison
Data Cloud, More than a CDP by Matt Robison
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 

Refactoring Ruby Code