SlideShare a Scribd company logo
1 of 119
Download to read offline
LET’S TALK ABOUT

    ruby
Ian Bishop
@ianbishop
Ruby is
Ruby is
simple in appearance,
Ruby is
simple in appearance,
but is very complex inside,
Ruby is
simple in appearance,
but is very complex inside,
just like our human body
Ruby is
simple in appearance,
but is very complex inside,
just like our human body
            - Yukihiro “matz” Matsumoto
philosophy
principle of
least surprise
principle of least surprise
array.length
string.length()
collection.size()
principle of least surprise
array.length
string.length()
collection.size()

array.length
string.length
collection.length
features
everything is an object
5.times do
    print “Everyone loves ruby!”
end
everything is an object
5.times
everything is a message
/abc/ === “abc”   “abc” === /abc/
=> true           => false
everything is a message
/abc/ === “abc”
=> true
everything is a message
/abc/



/abc/
everything is a message
/abc/



/abc/.send
everything is a message
/abc/ ===



/abc/.send(:===
everything is a message
/abc/ === “abc”



/abc/.send(:===, “abc”)
everything is a message
/abc/ === “abc”
=> true


/abc/.send(:===, “abc”)
=> true
everything is a message
/abc/ === “abc”   “abc” === /abc/
=> true           => false
everything is a message
case “HELLO”
when /^[a-z]*$/
     “lowercase”
when /^[A-Z]*$/
     “uppercase”
end

=> “uppercase”
everything is a message
case “HELLO”
when “hello”
     “lowercase”
when “HELLO”
     “uppercase”
end

=> “uppercase”
everything is a message
/abc/ === “abc”   “abc” === /abc/
=> true           => false
dynamic runtime
a = [1,2,3]
a.first
=> 1
a.second

NoMethodError: Undefined method
‘second’ for [1, 2, 3]:Array
dynamic runtime
class Array
     def second
          if self.length > 1
               return self[1]
          end
          nil
     end
end
dynamic runtime
a = [1,2,3]
a.first
=> 1
a.second
dynamic runtime
a = [1,2,3]
a.first
=> 1
a.second
=> 2
DEALING WITH

  data
using collections
a = [1,2,3]
using collections
a = [1,2,3,“meow”]
using collections
a.each do |x|
     puts x
end

1
2
3
meow
using collections
a.each
using collections
a.each do |x|

end
using collections
a.each do |x|
     puts x
end
using collections
a.each do |x|
     puts x
end

1
2
3
meow
.each
Iterate over elements in a collection
.map
Iterate over elements in a collection,
returning a new collection of
elements of the same size
using map
a = [1,2,3]
using map
a = [1,2,3]

a.map
using map
a = [1,2,3]

a.map do |x|

end
using map
a = [1,2,3]

a.map do |x|
     2 * x
end
using map
a = [1,2,3]

a.map do |x|
     return 2 * x
end
using map
a = [1,2,3]

a.map do |x|
     2 * x
end
using map
a = [1,2,3]

a.map do |x|
     2 * x
end

=> [2,4,6]
.map
Iterate over elements in a collection,
returning a new collection of
elements of the same size
.select
Iterate over elements in a collection,
returning elements which match a
specified criteria
using select
a = [1,2,3]
using select
a = [1,2,3]

a.select
using select
a = [1,2,3]

a.select do |x|

end
using select
a = [1,2,3]

a.select do |x|
     x.odd?
end
using select
a = [1,2,3]

a.select do |x|
     x.odd?
end

=> [1,3]
.select
Iterate over elements in a collection,
returning elements which match a
specified criteria
.reduce
Combines all elements in a collection
using a binary operation, returning
an accumulator value.
using reduce
a = [1,2,3]
using reduce
a = (1..100)
using reduce
a = (1..100)

a.reduce
using reduce
a = (1..100)

a.reduce do |sum, x|

end
using reduce
a = (1..100)

a.reduce do |sum, x|
     sum + x
end
using reduce
a = (1..100)

a.reduce do |sum, x|
     sum + x
end

=> 5050
.reduce
Combines all elements in a collection
using a binary operation, returning
an accumulator value.
.reduce
Combines all elements in a collection
using a binary operation, returning
an accumulator value.
using reduce (again)
a = (1..100)

a.reduce
using reduce (again)
a = (1..100)

a.reduce(:*)
using reduce (again)
a = (1..100)

a.reduce(:*)

=>9332621544394415268169923885626670049
071596826438162146859296389521759999322
991560894146397615651828625369792082722
37582511852109168640000000000000…
SOLVING
 HARDER
PROBLEMS
generating poker hands
building a deck of cards
suits = %w(S C H D)
building a deck of cards
suits = %w(S C H D)
=> [“S”, “C”, “H”, “D”]
building a deck of cards
suits = %w(S C H D)
=> [“S”, “C”, “H”, “D”]

“S C H D”.split /s+/
=> [“S”, “C”, “H”, “D”]
building a deck of cards
suits = %w(S C H D)
faces =
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
[1, 2, 3]

[“a”, “b”, “c”]
[1, 2, 3]
       x
[“a”, “b”, “c”]
cross product
[1, “a”], [1, “b”], [1, “c”],
[2, “a”], [2, “b”], [2, “c”],
[3, “a”], [3, “b”], [3, “c”]
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces)
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces)
=> [[“S”, 2], [“S”, 3], …, [“S”, “A”],
[“C”, 1], …, [“C”, “A”], …]
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces)
=> [“S2”, “S3”, …, “SA”, “C1”, …, “C2”,
…]
join(sep=$,) -> str
Returns a string created by converting each element
of the array to a string, seperated by sep.

 [ “a”, “b”, “c”].join
 => “abc”

 [ “a”, “b”, “c”].join(“-”)
 => “a-b-c”
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces)

deck = deck.map do |pair|
          pair.join
       end
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces)

deck.map! do |pair|
     pair.join
end
building a deck of cards


    .map!
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces)

deck.map! do |pair|
     pair.join
end
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces)

deck.map! { |pair| pair.join }
building a deck of cards
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces).map(&:join)
generating poker hands
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces).map(&:join)
sample(n) -> new_ary
Choose n random elements from the array.

The elements are chosen by using random
and unique indices in order to ensure that an
element doesn’t repeat itself unless the array
already contained duplicate elements.
generating poker hands
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces).map(&:join)

deck.sample(5)
generating poker hands
suits = %w(S C H D)
faces = (2..10).to_a + %w(J Q K A)
deck = suits.product(faces).map(&:join)

deck.sample(5)
=> [“C2”, “D5”, “S7”, “D8”, “C8”]
LET’S TALK ABOUT
   MAP REDUCE
LET’S TALK ABOUT
              ©
   MAP REDUCE
Count of URL Access Frequency
The map function processes logs of web page
requests and outputs <URL, 1>. The reduce
function adds together all values for the same
URL and emits a <URL, total count> pair.
            from Introduction to Parallel Programming and MapReduce (Google)
counting url access frequency
log
counting url access frequency
log
=> [“example.com”, “google.com”,
    “userevents.com”, “unb.ca”,
    “frederictonug.net”, ..]
Count of URL Access Frequency
The map function processes logs of web page
requests and outputs <URL, 1>. The reduce
function adds together all values for the same
URL and emits a <URL, total count> pair.
            from Introduction to Parallel Programming and MapReduce (Google)
generate count pairs
count_pairs = log.map do |url|
     [url, 1]
end
Count of URL Access Frequency
The map function processes logs of web page
requests and outputs <URL, 1>. The reduce
function adds together all values for the same URL
and emits a <URL, total count> pair.
            from Introduction to Parallel Programming and MapReduce (Google)
BUT FIRST
Collection of key-value
pairs.

Similar to an array, except
indexing is done via unique
keys.
brief introduction to hashes
my_hash = { :abc => 5, “def” => 9 }
brief introduction to hashes
my_hash = { :abc => 5, “def” => 9 }

my_hash[:abc]
brief introduction to hashes
my_hash = { :abc => 5, “def” => 9 }

my_hash[:abc]
=> 5
brief introduction to hashes
my_hash = { :abc => 5, “def” => 9 }

my_hash[:abc]
=> 5

my_hash[“def”] = 14
brief introduction to hashes
my_hash = { :abc => 5, “def” => 9 }

my_hash[:abc]
=> 5

my_hash[“def”] = 14
=> { :abc => 5, “def” => 14 }
Count of URL Access Frequency
The map function processes logs of web page
requests and outputs <URL, 1>. The reduce
function adds together all values for the same URL
and emits a <URL, total count> pair.
            from Introduction to Parallel Programming and MapReduce (Google)
combining count pairs
count_pairs.reduce
combining count pairs
count_pairs.reduce({})
combining count pairs
count_pairs.reduce({}) do |hash, pair|




end
combining count pairs
count_pairs.reduce({}) do |hash, pair|
     url, count = pair




end
combining count pairs
count_pairs.reduce({}) do |hash, pair|
     url, count = pair
     if hash.has_key? url
          hash[url] += count




end
combining count pairs
count_pairs.reduce({}) do |hash, pair|
     url, count = pair
     if hash.has_key? url
          hash[url] += count
     else
          hash[url] = count
     end

end
combining count pairs
count_pairs.reduce({}) do |hash, pair|
     url, count = pair
     if hash.has_key? url
          hash[url] += count
     else
          hash[url] = count
     end
     hash
end
counting url access frequency
log = [“example.com”, “google.com”,
“example.com”, “unb.ca”]
counting url access frequency
log = [“example.com”, “google.com”,
“example.com”, “unb.ca”]

=> { “example.com” => 2,
     “google.com” => 1,
     “unb.ca” => 1 }

More Related Content

What's hot

好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
Takashi Kitano
 
Clustering com numpy e cython
Clustering com numpy e cythonClustering com numpy e cython
Clustering com numpy e cython
Anderson Dantas
 
Palestra sobre Collections com Python
Palestra sobre Collections com PythonPalestra sobre Collections com Python
Palestra sobre Collections com Python
pugpe
 
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingGareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Yury Chemerkin
 

What's hot (20)

{tidygraph}と{ggraph}によるモダンなネットワーク分析
{tidygraph}と{ggraph}によるモダンなネットワーク分析{tidygraph}と{ggraph}によるモダンなネットワーク分析
{tidygraph}と{ggraph}によるモダンなネットワーク分析
 
Advanced Data Visualization Examples with R-Part II
Advanced Data Visualization Examples with R-Part IIAdvanced Data Visualization Examples with R-Part II
Advanced Data Visualization Examples with R-Part II
 
Python for Data Science and Scientific Computing
Python for Data Science and Scientific ComputingPython for Data Science and Scientific Computing
Python for Data Science and Scientific Computing
 
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
好みの日本酒を呑みたい! 〜さけのわデータで探す自分好みの酒〜
 
PLOTCON NYC: Behind Every Great Plot There's a Great Deal of Wrangling
PLOTCON NYC: Behind Every Great Plot There's a Great Deal of WranglingPLOTCON NYC: Behind Every Great Plot There's a Great Deal of Wrangling
PLOTCON NYC: Behind Every Great Plot There's a Great Deal of Wrangling
 
{shiny}と{leaflet}による地図アプリ開発Tips
{shiny}と{leaflet}による地図アプリ開発Tips{shiny}と{leaflet}による地図アプリ開発Tips
{shiny}と{leaflet}による地図アプリ開発Tips
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
ScalaBlitz
ScalaBlitzScalaBlitz
ScalaBlitz
 
Clustering com numpy e cython
Clustering com numpy e cythonClustering com numpy e cython
Clustering com numpy e cython
 
Palestra sobre Collections com Python
Palestra sobre Collections com PythonPalestra sobre Collections com Python
Palestra sobre Collections com Python
 
The Ring programming language version 1.9 book - Part 29 of 210
The Ring programming language version 1.9 book - Part 29 of 210The Ring programming language version 1.9 book - Part 29 of 210
The Ring programming language version 1.9 book - Part 29 of 210
 
Digital Electronics
Digital ElectronicsDigital Electronics
Digital Electronics
 
{tidygraph}と{ggraph}による モダンなネットワーク分析(未公開ver)
{tidygraph}と{ggraph}による モダンなネットワーク分析(未公開ver){tidygraph}と{ggraph}による モダンなネットワーク分析(未公開ver)
{tidygraph}と{ggraph}による モダンなネットワーク分析(未公開ver)
 
令和から本気出す
令和から本気出す令和から本気出す
令和から本気出す
 
Numpy python cheat_sheet
Numpy python cheat_sheetNumpy python cheat_sheet
Numpy python cheat_sheet
 
ScalaMeter 2014
ScalaMeter 2014ScalaMeter 2014
ScalaMeter 2014
 
The Ring programming language version 1.8 book - Part 27 of 202
The Ring programming language version 1.8 book - Part 27 of 202The Ring programming language version 1.8 book - Part 27 of 202
The Ring programming language version 1.8 book - Part 27 of 202
 
Scala Parallel Collections
Scala Parallel CollectionsScala Parallel Collections
Scala Parallel Collections
 
Optimization and Mathematical Programming in R and ROI - R Optimization Infra...
Optimization and Mathematical Programming in R and ROI - R Optimization Infra...Optimization and Mathematical Programming in R and ROI - R Optimization Infra...
Optimization and Mathematical Programming in R and ROI - R Optimization Infra...
 
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzingGareth hayes. non alphanumeric javascript-php and shared fuzzing
Gareth hayes. non alphanumeric javascript-php and shared fuzzing
 

Similar to Let’s Talk About Ruby

Useful javascript
Useful javascriptUseful javascript
Useful javascript
Lei Kang
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
Dmitry Buzdin
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
aztack
 

Similar to Let’s Talk About Ruby (20)

Useful javascript
Useful javascriptUseful javascript
Useful javascript
 
Functional Programming with Groovy
Functional Programming with GroovyFunctional Programming with Groovy
Functional Programming with Groovy
 
7 Habits For a More Functional Swift
7 Habits For a More Functional Swift7 Habits For a More Functional Swift
7 Habits For a More Functional Swift
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
A quick introduction to R
A quick introduction to RA quick introduction to R
A quick introduction to R
 
Basic R Data Manipulation
Basic R Data ManipulationBasic R Data Manipulation
Basic R Data Manipulation
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
Scala by Luc Duponcheel
Scala by Luc DuponcheelScala by Luc Duponcheel
Scala by Luc Duponcheel
 
Functional programming in ruby
Functional programming in rubyFunctional programming in ruby
Functional programming in ruby
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced Ruby
 
NumPy_Broadcasting Data Science - Python.pptx
NumPy_Broadcasting Data Science - Python.pptxNumPy_Broadcasting Data Science - Python.pptx
NumPy_Broadcasting Data Science - Python.pptx
 
Monadologie
MonadologieMonadologie
Monadologie
 
Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015Will it Blend? - ScalaSyd February 2015
Will it Blend? - ScalaSyd February 2015
 
18. Java associative arrays
18. Java associative arrays18. Java associative arrays
18. Java associative arrays
 
An overview of Python 2.7
An overview of Python 2.7An overview of Python 2.7
An overview of Python 2.7
 
Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!Beginning Haskell, Dive In, Its Not That Scary!
Beginning Haskell, Dive In, Its Not That Scary!
 
R code for data manipulation
R code for data manipulationR code for data manipulation
R code for data manipulation
 
R code for data manipulation
R code for data manipulationR code for data manipulation
R code for data manipulation
 
[1062BPY12001] Data analysis with R / week 2
[1062BPY12001] Data analysis with R / week 2[1062BPY12001] Data analysis with R / week 2
[1062BPY12001] Data analysis with R / week 2
 
Map, Reduce and Filter in Swift
Map, Reduce and Filter in SwiftMap, Reduce and Filter in Swift
Map, Reduce and Filter in Swift
 

Recently uploaded

Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
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
panagenda
 

Recently uploaded (20)

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
 
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
Biography Of Angeliki Cooney | Senior Vice President Life Sciences | Albany, ...
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
Apidays New York 2024 - APIs in 2030: The Risk of Technological Sleepwalk by ...
 
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
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
 
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ..."I see eyes in my soup": How Delivery Hero implemented the safety system for ...
"I see eyes in my soup": How Delivery Hero implemented the safety system for ...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
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, ...
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
Cyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdfCyberprint. Dark Pink Apt Group [EN].pdf
Cyberprint. Dark Pink Apt Group [EN].pdf
 
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
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
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
 

Let’s Talk About Ruby