SlideShare a Scribd company logo
TEST
From Ruby to Scala
From Ruby to Scala
Hello, is there Rubyist?
(When I moved) 
From Ruby 
to Scala 
@todesking 
https://www.flickr.com/photos/7armyjmtc/14249465709
Who: 
@todesking 
uses twitter and GitHub 
web: todesking.com
Working at 
Platinum Sponsor
My background 
• Sistem Integrator(2008-2012) 
• Buisiness batches 
• Recommendation system 
• With Java 
• Social game servicer 
• Browser based social game server 
• With Rails 
• DSP servicer 
• Adverting technology(Real-time bidding, user trakcing, machine 
learning) 
• With Scala 
• Vim
What is DSP 
Ad 
Clients 
DSP SSP 
I'm here Pages 
real time bidding(RTB) 
Web 
• "Demand Side Platform" 
• You can find detailed description in at Internet.
Today I NOT talk to: 
• How to build high-performance system 
• DO THE RIGHT THING and KEEP GOING, 
thats all. 
• How to speed up compilation time 
• BUY FASTER MACHINE 
• Whitch is greatest language 
• Every language has own good things 
• BE PEACEFUL
I moved from Ruby 
to Scala, in this April 
• That is smoother than I thought. 
• Basically, Ruby and Scala has common attributes 
• object-oriented and functional paradigm 
• Modern features for productivity and fun
Ruby and Scala is Class-based Object 
Oriented language 
• Class based object oriented language 
class Person(val name:String, val age:Option[Int]) { 
def hello():Unit = { 
class Person < Struct.new(:name, :age) 
def hello 
puts "Hello there, my name is #{name}." 
end 
end 
println(s"Hello there, my name is ${name}.") 
} 
}
At first: Common attributes of Ruby 
and Scala 
• Class based object oriented language with 
functional features 
def sumOfAge(people:Seq[Person]):Int = { 
people.map(_.age).flatten.foldLeft(0)(_ + _) 
} 
def sum_of_age(people) 
people.map(&:age).compact.reduce(0, &:+) 
end
At first: Common attributes of Ruby 
and Scala 
• "Fun" language 
• "Rubyをキメると気持ちいい"(Matz) 
• I can't translate it... 
•  →  
• "Maybe most important is that programming in 
Scala tends to be very enjoyable."
Today's theme: 
How these languages do things 
in different way
Class definition 
class Person(val name:String, val age:Option[Int]) 
val person = new Person("tode sking", Some(31)) 
class Person < Struct.new(:name, :age) 
end 
person = Person.new("tode sking", 31)
Class definition in Ruby 
"class" for class 
definition 
class Person < Struct.new(:name, :age) 
"<" means "extends" Create new instance of Struct 
WHAT?! 
Creating new instance at class definition?!?!
Let's begin most plain case 
class Person 
def initialize(name, age) 
@name = name 
@age = age 
end 
def name; @name; end 
def name=(val); @name = val; end 
def age; @age; end 
def age=(val); @age = val; end 
end 
"def" for method 
definition 
method named "initialize" 
is treated as ctor 
"@name" is instance variable 
getter and setter methods 
Lot of boilerplate
Auto generating accessor method 
in Ruby 
class Person 
def initialize(name, age) ... 
attr_reader :name 
attr_reader :age 
end 
"attr_reader" is keyword for 
generating accessor method 
"attr_writer" and "attr_reader" 
is also available 
NO, actually it is not 
KEYWORD 
It just a METHOD.
Auto generating accessor method 
in Ruby 
attr_accessor :name 
≒ 
define_method("name") { @name } 
define_method("name=") {|val| @name = val } 
≒ 
def name; @name; end 
def mane=(val); @name = val; end
Ruby is DYNAMIC language 
• EVERYTHING is object 
• Class is object too 
• o = Object.new; o.class => Object 
• If you want to create new class, try A = Class.new 
• (assign constant A to fresh class object) 
• To define a method to A, try A.define_method(:foo){...} 
• (actually, define_method is "private". You should 
use A.instance_eval { define_method(:foo) ... })
It called "Macro" in Ruby 
• Such method called "macro"(Actually, it is just a 
method!!) 
• Ruby has no "compile-time". all execution is in 
"runtime"
Defining accessor method: 
Ruby and Scala 
• scala 
• var foo 
• roughly equal to { private[this] var foo_; def foo 
= foo_ } 
• specialized syntax for accessor 
• Ruby 
• attr_* 
• Enhance class definition with DSLs
Auto generating accessor method 
in Ruby 
class Person < Struct.new(:name, :age) 
Create a new instance of 
Struct 
Struct is a kind of Class 
≒ 
PersonBase = Struct.new(:name, :age) 
class Person < PersonBase
Auto generating accessor method 
in Ruby 
Struct.new(:name, age) returns class that like 
class (unnamed) 
def initialize(name, age) 
@name, @age = name, age 
end 
attr_accessor :name 
attr_accessor :age 
# other utility methods... 
end[
Class definition 
class Person(val name:String, val age:Option[Int]) 
val person = new Person("tode sking", Some(31)) 
class Person < Struct.new(:name, :age) 
end 
person = Person.new("tode sking", 31)
Function as value 
• Scala: 
• val f:Int => Int = _ + 1 
• f(1) //=> 2 
• val g:Any => String = _.toString 
• Ruby 
• f = ->(x){x + 1} 
• f.call(1) or f[1] or f.(1) 
• mehod and value is strongly separated 
• g = ->(x){x.to_s}
Functions as value in other 
languages 
• Scheme: f, (f a b) 
• javascript: f, f(a, b) 
• Common Lisp: #'f, (f a b), (funcall #'f (list arg1 
arg2))
Use function as value: Scala 
case 
• def foo(x:Int):String 
• val f = foo // not works 
• val f = foo _ // works 
• def bar(f:Int => String) 
• bar(foo) // works 
• bar(x => x.toString) 
• bar { x => x.toString } 
• bar(_.toString)
Use function as value: Ruby 
case 
• def foo(x) 
• f = method(:foo) 
• f = ->(x){ foo(x) } 
• def bar1(f) 
• def bar2(&f) 
• bar1(f) 
• bar2 {|x| foo(x) } 
• bar2(&f)
Use any object as function 
• [1, 2, 3].map(&:to_s) #=> ["1", "2", "3"] 
• map(&:to_s) 
• It behave like Scala's map(_.toString) 
• If block value is given, Ruby runtime call its 
"to_proc" method and use the result value as 
block. 
• Ruby's Symbol class has to_proc method 
• :to_s.to_proc #=> {|obj| obj.to_s }
Collections 
• Literals 
• Ruby: {}, [] 
• Scala: () 
• Neither list nor hash literals
Collections 
Map HashMap 
TupleN 
LinkedHashMa 
p 
HashMap 
Seq 
immutabl 
e 
LinkedHashMa 
p 
List 
Stack 
mutable 
Buffer 
Traversabl 
e 
Enumerable 
Hash 
{key => value} 
Array 
[1, 2, 3] 
(a, b)
Ruby has "Big" classes 
• "Array" is generic, mutable data structure, it can, 
push/pop, shift/pop, insert, indexed and 
sequential access, and also used as tuple 
• "Hash" is generic, mutable (and only) key-vakue 
map structure in Ruby standard library
Transform collection in Big-class 
style 
• [1, 2, 3].map(&:to_s) #=> ["1", "2", "3"] 
• Ruby has few Big collection classes. Everything 
goes simple.
Transform collection in Scala 
• Iterator[A].map(f:A => B):Iterator[B] 
• List[A].map(f:A => B):List[B] 
• BitSet.map(f:Int => Int):BitSet 
• BitSet.map(f:Int => String):SortedSet[String] 
• Magic "CanBuildFrom" implicit argument is used to 
solve this problem. 
• def map[B, That](f: (Int) ⇒ B)(implicit bf: 
CanBuildFrom[A, B, That]): That 
• Scala used types VERY MUCH.It's cool.
How to ehnahce existing class 
in Scala 
• implicit conversion 
• subclassing
How to ehnahce existing class 
in Ruby 
• subclassing 
• direct modification(simplly 
overwrite/alias_method_chain) 
• define singleton method 
• include/extend 
• refinements
How to handle "non-existens 
value" 
• Scala: Option[T] 
• Ruby: ♥nil♥ 
• false and nil is "falsy". Other values are "truthy". 
• obj.foo if obj # call obj.foo if obj is not nil 
• obj.try(:foo) # same (ActiveSupport feature)
Conclusion 
• Ruby and Scala is very different, but they share 
same goal: be productive, be fun. 
• There are many different approach to solve 
problems.We can learn things and achieve fresh 
surprise from other culture. 
Have a fun with various programming!!
Today I want talk to: 
• Libraries 
• rubygems: High accessibility 
• Source distribution 
• Easy to publish 
• maven repo: Top on Java ecosystem 
• Some impedance missmatch 
• Binary distribution 
• Bit difficult to publish, especially official repo. 
• Build/Task system 
• Rake: Simple scripting with internal DSL 
• Sbt: Type-safe and immutable dependency graph construction with cool := ++= <<= s 
• It's Scala's way!! 
• Community 
• Ruby: Humanity 
• Love emotional context 
• Scala: Types 
• Love Monads !!!!

More Related Content

PDF
What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!
PDF
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
PDF
The Evolution of Scala / Scala進化論
PDF
Solid And Sustainable Development in Scala
PDF
Scala : language of the future
PDF
camel-scala.pdf
PDF
Scala @ TechMeetup Edinburgh
PDF
A Brief, but Dense, Intro to Scala
What's a macro?: Learning by Examples / Scalaのマクロに実用例から触れてみよう!
Weaving Dataflows with Silk - ScalaMatsuri 2014, Tokyo
The Evolution of Scala / Scala進化論
Solid And Sustainable Development in Scala
Scala : language of the future
camel-scala.pdf
Scala @ TechMeetup Edinburgh
A Brief, but Dense, Intro to Scala

What's hot (20)

PDF
Scala profiling
PPTX
A Brief Intro to Scala
PDF
Introduction to Scala
ODP
A Tour Of Scala
PDF
[Start] Scala
KEY
Scala Introduction
PPTX
Scala Refactoring for Fun and Profit (Japanese subtitles)
PPTX
Speaking Scala: Refactoring for Fun and Profit (Workshop)
PDF
Scala in Practice
PPTX
Scala in practice
PDF
Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介
PDF
Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...
PDF
Java 8 and Beyond, a Scala Story
PPTX
Scala Matsuri 2016: Japanese Text Mining with Scala and Spark
PDF
Objective-C Is Not Java
KEY
Static or Dynamic Typing? Why not both?
KEY
Java to Scala: Why & How
PPT
55 New Features in Java 7
PDF
User defined-functions-cassandra-summit-eu-2014
PDF
Introduction to Scala for Java Developers
Scala profiling
A Brief Intro to Scala
Introduction to Scala
A Tour Of Scala
[Start] Scala
Scala Introduction
Scala Refactoring for Fun and Profit (Japanese subtitles)
Speaking Scala: Refactoring for Fun and Profit (Workshop)
Scala in Practice
Scala in practice
Introduction to Spark SQL and Catalyst / Spark SQLおよびCalalystの紹介
Scala in-practice-3-years by Patric Fornasier, Springr, presented at Pune Sca...
Java 8 and Beyond, a Scala Story
Scala Matsuri 2016: Japanese Text Mining with Scala and Spark
Objective-C Is Not Java
Static or Dynamic Typing? Why not both?
Java to Scala: Why & How
55 New Features in Java 7
User defined-functions-cassandra-summit-eu-2014
Introduction to Scala for Java Developers
Ad

Viewers also liked (20)

PDF
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
PDF
Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ...
PDF
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
PPTX
[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫
PDF
GitBucket: The perfect Github clone by Scala
PDF
sbt, past and future / sbt, 傾向と対策
PPTX
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
PDF
Node.js vs Play Framework (with Japanese subtitles)
PDF
Nyandoc: Scaladoc/Javadoc to markdown converter
KEY
スタート形態素解析
ODP
精神論によるいきいきとした組織づくりのご提案
PDF
(うしなわれた)Fluentd output-convert_structure
PDF
仕様変更で死なないためのユニットテスト
PDF
概観テキストマイニング
KEY
貧者のための入力デバイス
PDF
Scalaのコンパイルを3倍速くした話
PDF
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
PPT
分散バージョン管理システムGitの紹介
PPTX
個人ユースGitのススメ
PDF
芸者東京とScala〜おみせやさんから脳トレクエストまでの軌跡〜
Xitrum Web Framework Live Coding Demos / Xitrum Web Framework ライブコーディング
Scarab: SAT-based Constraint Programming System in Scala / Scala上で実現された制約プログラ...
Scalable Generator: Using Scala in SIer Business (ScalaMatsuri)
[ScalaMatsuri] グリー初のscalaプロダクト!チャットサービス公開までの苦労と工夫
GitBucket: The perfect Github clone by Scala
sbt, past and future / sbt, 傾向と対策
Building a Unified Data Pipline in Spark / Apache Sparkを用いたBig Dataパイプラインの統一
Node.js vs Play Framework (with Japanese subtitles)
Nyandoc: Scaladoc/Javadoc to markdown converter
スタート形態素解析
精神論によるいきいきとした組織づくりのご提案
(うしなわれた)Fluentd output-convert_structure
仕様変更で死なないためのユニットテスト
概観テキストマイニング
貧者のための入力デバイス
Scalaのコンパイルを3倍速くした話
Activity, Fragment, CustomView の使い分け - マッチョなActivityにさよならする方法 -
分散バージョン管理システムGitの紹介
個人ユースGitのススメ
芸者東京とScala〜おみせやさんから脳トレクエストまでの軌跡〜
Ad

Similar to From Ruby to Scala (20)

PPTX
Code for Startup MVP (Ruby on Rails) Session 2
PDF
JavaScript in 2016
PPTX
JavaScript in 2016 (Codemotion Rome)
PPTX
Ruby :: Training 1
PDF
BoxLang JVM Language : The Future is Dynamic
PPTX
A brief tour of modern Java
PDF
Scala in practice - 3 years later
PDF
Introducing BoxLang : A new JVM language for productivity and modularity!
PPTX
Taxonomy of Scala
PDF
Scala In The Wild
PPTX
Introduction to Kotlin Language and its application to Android platform
PPT
Rapid Application Development using Ruby on Rails
PPTX
Core java complete ppt(note)
PDF
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
PPT
Rubyforjavaprogrammers 1210167973516759-9
PPT
Rubyforjavaprogrammers 1210167973516759-9
PDF
Why Java Sucks and C# Rocks (Final)
PPT
Javascript
PDF
JavaScript For CSharp Developer
PDF
Full metal mongo
Code for Startup MVP (Ruby on Rails) Session 2
JavaScript in 2016
JavaScript in 2016 (Codemotion Rome)
Ruby :: Training 1
BoxLang JVM Language : The Future is Dynamic
A brief tour of modern Java
Scala in practice - 3 years later
Introducing BoxLang : A new JVM language for productivity and modularity!
Taxonomy of Scala
Scala In The Wild
Introduction to Kotlin Language and its application to Android platform
Rapid Application Development using Ruby on Rails
Core java complete ppt(note)
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
Rubyforjavaprogrammers 1210167973516759-9
Rubyforjavaprogrammers 1210167973516759-9
Why Java Sucks and C# Rocks (Final)
Javascript
JavaScript For CSharp Developer
Full metal mongo

Recently uploaded (20)

PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PDF
MIND Revenue Release Quarter 2 2025 Press Release
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
Cloud computing and distributed systems.
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Review of recent advances in non-invasive hemoglobin estimation
PDF
Machine learning based COVID-19 study performance prediction
PDF
The Rise and Fall of 3GPP – Time for a Sabbatical?
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
DOCX
The AUB Centre for AI in Media Proposal.docx
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
MIND Revenue Release Quarter 2 2025 Press Release
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Unlocking AI with Model Context Protocol (MCP)
Cloud computing and distributed systems.
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Review of recent advances in non-invasive hemoglobin estimation
Machine learning based COVID-19 study performance prediction
The Rise and Fall of 3GPP – Time for a Sabbatical?
Agricultural_Statistics_at_a_Glance_2022_0.pdf
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Programs and apps: productivity, graphics, security and other tools
Mobile App Security Testing_ A Comprehensive Guide.pdf
The AUB Centre for AI in Media Proposal.docx
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
NewMind AI Weekly Chronicles - August'25 Week I
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Dropbox Q2 2025 Financial Results & Investor Presentation

From Ruby to Scala

  • 4. Hello, is there Rubyist?
  • 5. (When I moved) From Ruby to Scala @todesking https://www.flickr.com/photos/7armyjmtc/14249465709
  • 6. Who: @todesking uses twitter and GitHub web: todesking.com
  • 8. My background • Sistem Integrator(2008-2012) • Buisiness batches • Recommendation system • With Java • Social game servicer • Browser based social game server • With Rails • DSP servicer • Adverting technology(Real-time bidding, user trakcing, machine learning) • With Scala • Vim
  • 9. What is DSP Ad Clients DSP SSP I'm here Pages real time bidding(RTB) Web • "Demand Side Platform" • You can find detailed description in at Internet.
  • 10. Today I NOT talk to: • How to build high-performance system • DO THE RIGHT THING and KEEP GOING, thats all. • How to speed up compilation time • BUY FASTER MACHINE • Whitch is greatest language • Every language has own good things • BE PEACEFUL
  • 11. I moved from Ruby to Scala, in this April • That is smoother than I thought. • Basically, Ruby and Scala has common attributes • object-oriented and functional paradigm • Modern features for productivity and fun
  • 12. Ruby and Scala is Class-based Object Oriented language • Class based object oriented language class Person(val name:String, val age:Option[Int]) { def hello():Unit = { class Person < Struct.new(:name, :age) def hello puts "Hello there, my name is #{name}." end end println(s"Hello there, my name is ${name}.") } }
  • 13. At first: Common attributes of Ruby and Scala • Class based object oriented language with functional features def sumOfAge(people:Seq[Person]):Int = { people.map(_.age).flatten.foldLeft(0)(_ + _) } def sum_of_age(people) people.map(&:age).compact.reduce(0, &:+) end
  • 14. At first: Common attributes of Ruby and Scala • "Fun" language • "Rubyをキメると気持ちいい"(Matz) • I can't translate it... •  →  • "Maybe most important is that programming in Scala tends to be very enjoyable."
  • 15. Today's theme: How these languages do things in different way
  • 16. Class definition class Person(val name:String, val age:Option[Int]) val person = new Person("tode sking", Some(31)) class Person < Struct.new(:name, :age) end person = Person.new("tode sking", 31)
  • 17. Class definition in Ruby "class" for class definition class Person < Struct.new(:name, :age) "<" means "extends" Create new instance of Struct WHAT?! Creating new instance at class definition?!?!
  • 18. Let's begin most plain case class Person def initialize(name, age) @name = name @age = age end def name; @name; end def name=(val); @name = val; end def age; @age; end def age=(val); @age = val; end end "def" for method definition method named "initialize" is treated as ctor "@name" is instance variable getter and setter methods Lot of boilerplate
  • 19. Auto generating accessor method in Ruby class Person def initialize(name, age) ... attr_reader :name attr_reader :age end "attr_reader" is keyword for generating accessor method "attr_writer" and "attr_reader" is also available NO, actually it is not KEYWORD It just a METHOD.
  • 20. Auto generating accessor method in Ruby attr_accessor :name ≒ define_method("name") { @name } define_method("name=") {|val| @name = val } ≒ def name; @name; end def mane=(val); @name = val; end
  • 21. Ruby is DYNAMIC language • EVERYTHING is object • Class is object too • o = Object.new; o.class => Object • If you want to create new class, try A = Class.new • (assign constant A to fresh class object) • To define a method to A, try A.define_method(:foo){...} • (actually, define_method is "private". You should use A.instance_eval { define_method(:foo) ... })
  • 22. It called "Macro" in Ruby • Such method called "macro"(Actually, it is just a method!!) • Ruby has no "compile-time". all execution is in "runtime"
  • 23. Defining accessor method: Ruby and Scala • scala • var foo • roughly equal to { private[this] var foo_; def foo = foo_ } • specialized syntax for accessor • Ruby • attr_* • Enhance class definition with DSLs
  • 24. Auto generating accessor method in Ruby class Person < Struct.new(:name, :age) Create a new instance of Struct Struct is a kind of Class ≒ PersonBase = Struct.new(:name, :age) class Person < PersonBase
  • 25. Auto generating accessor method in Ruby Struct.new(:name, age) returns class that like class (unnamed) def initialize(name, age) @name, @age = name, age end attr_accessor :name attr_accessor :age # other utility methods... end[
  • 26. Class definition class Person(val name:String, val age:Option[Int]) val person = new Person("tode sking", Some(31)) class Person < Struct.new(:name, :age) end person = Person.new("tode sking", 31)
  • 27. Function as value • Scala: • val f:Int => Int = _ + 1 • f(1) //=> 2 • val g:Any => String = _.toString • Ruby • f = ->(x){x + 1} • f.call(1) or f[1] or f.(1) • mehod and value is strongly separated • g = ->(x){x.to_s}
  • 28. Functions as value in other languages • Scheme: f, (f a b) • javascript: f, f(a, b) • Common Lisp: #'f, (f a b), (funcall #'f (list arg1 arg2))
  • 29. Use function as value: Scala case • def foo(x:Int):String • val f = foo // not works • val f = foo _ // works • def bar(f:Int => String) • bar(foo) // works • bar(x => x.toString) • bar { x => x.toString } • bar(_.toString)
  • 30. Use function as value: Ruby case • def foo(x) • f = method(:foo) • f = ->(x){ foo(x) } • def bar1(f) • def bar2(&f) • bar1(f) • bar2 {|x| foo(x) } • bar2(&f)
  • 31. Use any object as function • [1, 2, 3].map(&:to_s) #=> ["1", "2", "3"] • map(&:to_s) • It behave like Scala's map(_.toString) • If block value is given, Ruby runtime call its "to_proc" method and use the result value as block. • Ruby's Symbol class has to_proc method • :to_s.to_proc #=> {|obj| obj.to_s }
  • 32. Collections • Literals • Ruby: {}, [] • Scala: () • Neither list nor hash literals
  • 33. Collections Map HashMap TupleN LinkedHashMa p HashMap Seq immutabl e LinkedHashMa p List Stack mutable Buffer Traversabl e Enumerable Hash {key => value} Array [1, 2, 3] (a, b)
  • 34. Ruby has "Big" classes • "Array" is generic, mutable data structure, it can, push/pop, shift/pop, insert, indexed and sequential access, and also used as tuple • "Hash" is generic, mutable (and only) key-vakue map structure in Ruby standard library
  • 35. Transform collection in Big-class style • [1, 2, 3].map(&:to_s) #=> ["1", "2", "3"] • Ruby has few Big collection classes. Everything goes simple.
  • 36. Transform collection in Scala • Iterator[A].map(f:A => B):Iterator[B] • List[A].map(f:A => B):List[B] • BitSet.map(f:Int => Int):BitSet • BitSet.map(f:Int => String):SortedSet[String] • Magic "CanBuildFrom" implicit argument is used to solve this problem. • def map[B, That](f: (Int) ⇒ B)(implicit bf: CanBuildFrom[A, B, That]): That • Scala used types VERY MUCH.It's cool.
  • 37. How to ehnahce existing class in Scala • implicit conversion • subclassing
  • 38. How to ehnahce existing class in Ruby • subclassing • direct modification(simplly overwrite/alias_method_chain) • define singleton method • include/extend • refinements
  • 39. How to handle "non-existens value" • Scala: Option[T] • Ruby: ♥nil♥ • false and nil is "falsy". Other values are "truthy". • obj.foo if obj # call obj.foo if obj is not nil • obj.try(:foo) # same (ActiveSupport feature)
  • 40. Conclusion • Ruby and Scala is very different, but they share same goal: be productive, be fun. • There are many different approach to solve problems.We can learn things and achieve fresh surprise from other culture. Have a fun with various programming!!
  • 41. Today I want talk to: • Libraries • rubygems: High accessibility • Source distribution • Easy to publish • maven repo: Top on Java ecosystem • Some impedance missmatch • Binary distribution • Bit difficult to publish, especially official repo. • Build/Task system • Rake: Simple scripting with internal DSL • Sbt: Type-safe and immutable dependency graph construction with cool := ++= <<= s • It's Scala's way!! • Community • Ruby: Humanity • Love emotional context • Scala: Types • Love Monads !!!!

Editor's Notes

  • #4: はい、というわけでね、プレゼン始めさせてもらおうと思うんですけど
  • #5: まず最初に質問なんですが、この会場にRubyを使ったことある方どれくらいいらっしゃいますか? フムー 本日はRubyの話をしに来ました
  • #6: というわけでFrom Ruby to Scalaというタイトルで発表させていただきます。戦争が起きそうなタイトルですけど、RubyはクソだからScalaに行こうぜってわけじゃなくて私がRubyからScalaに行った時の体験談についての話をします!
  • #7: はじめまして皆さん。TwitterやGitHubではtodeskingという名前でやってます。
  • #8: 今の仕事はMaverickという会社で、Scalaで広告システムを作ってます。 ちなみにMaverickというのはScalaMatsuriのプラチナスポンサーです!!
  • #9: まず私のバックグラウンドについてお話します。 最初はSIerでJavaやってました。推薦エンジンとか、バッチを書くのがメイン。 次の会社ではRuby/Railsでソーシャルブラウザゲームのサーバサイドを担当してました。 今の会社ではScalaで広告システムを作ってます。
  • #10: DSPというのがどういうものかについてはぐぐってください。 簡単に言うとWebの広告配信を代行するサービスです。クライアントから広告を集めて、SSPと呼ばれるサービスの広告枠オークションを通じて広告を配信します。 オークションは誰かが広告枠のあるページを閲覧するたびに行われるため、膨大なリクエストを数十msの遅延で返す必要があります。その制限の中で、広告のCVRを上げるために機械学習など使ったインテリジェントな判断をする必要があるのでむずかしいですね。 まあ今日はそういう話しないんですけどね。
  • #11: 本題に入る前に、今日話すことについて説明します。 まずScalaでハイパフォーマンスシステムを作る方法については触れません。これは一言で言うと「正しいことをやり、それを続ける」ことで実現可能です。遅い処理を書かない、ボトルネックを見つけて最適化する、まずい設計は直す。それを続けるだけです。以上。 みんな大好きなコンパイル時間についての話もしません。速いマシンを買うと改善するという噂があります!! RubyとScalaはどちらが良いのかについても話しません。最近は動的型付けと静的型付けの対立を煽るような動きがありますが、それぞれの言語には独自のいいところがあるので各位仲良くしましょう!!
  • #12: さて、私はこの4月にRubyからScalaに乗り換えたわけですけど、移行は思ったよりスムーズにいきました。 RubyとScalaは、かなり似た特徴を持っています。 どちらもOOベースで関数型の機能を取り入れていること。そして、生産性と楽しさを重視していること。
  • #13: まず、どちらもクラスベースのオブジェクト指向言語です。それぞれの言語でほぼ同じ内容のクラスを定義してみました。どちらの言語も、簡潔な記法でクラスを定義するための機能を備えています。
  • #14: また、関数型の機能を取り入れており、無名の関数をインラインで作ったり関数を値として扱うための機構を備えています。
  • #15: そして、一番の共通点は「楽しさ」をコンセプトの一つにしていることです。Rubyの作者であるMatzの”Rubyをキメると気持ちいい"という名言は有名ですし、Martin Odersky氏もScalaの特徴としてScalable, Functionalなどの特徴と並んでFunを挙げています。
  • #16: 先ほど紹介したように、RubyとScalaは似た方向性を持つ言語です。 しかし、その目的を実現するための方法は二つの言語で大きく違います。 今日は、この二つの言語がどのようなアプローチで問題を解決しているのかを紹介しようと思います。
  • #17: これは先ほども出した、Personクラスの定義です。 Scalaの定義は、まあ見たままですね。この一行でnameとageという二つのメンバを持つPersonクラスを定義しなさいという、そういう文です。 さて、Rubyにおいてクラス定義がどのようにされているのか見てみましょう。
  • #18: クラス定義はclassというキーワードから始めるのはRubyと同様。 小なり記号は、このクラスが右のクラスを継承することを表します。 余談ですが、Scalaでもextendsとかwithとかやめて記号で書きたいですねー。 というわけで、ここではStructをnewした結果を継承したPersonクラスを定義していますね。 なんだって??? 何故かクラス定義時に新しいインスタンスを作っているんですね。 この例は複雑なので、まずは簡単な例から見てみます。
  • #19: 先ほどと同じクラス定義を、なるべく基本機能のみで書いてみました。 defキーワードでメソッド定義されるのはScalaと同様。initializeという名前のメソッドはコンストラクタになります。 @のついた識別子はインスタンス変数を表します。コンストラクタでnameとageを受け取り、同名のインスタンス変数にセットしています。 その下に並んでいるのはインスタンス変数に対するゲッタとセッタメソッドの定義です。 この単純なやりかただと、まるでジャバのように大量のボイラープレートコードを書く必要があってだるいですね。
  • #20: そこでアクセサメソッドの定義をもっと単純にしたいと思います。 先ほどのメソッド定義の代わりに、attr_readerキーワードを使います。 これを使用することで、指定した名前のセッタとゲッタが自動生成されます。 他にもゲッタのみを生成するattr_reader、セッタのみを生成するattr_writerも用意されています。 さて、今キーワードと言ったけど、それは嘘でした。ここでやっているのは、単なるattr_accessorというメソッドの呼び出しです。
  • #21: クラス定義内に書いた式はScalaだとコンストラクタ扱いになりますが、Rubyの場合はそのクラス定義が読まれたタイミングで評価されます。今の例だと、自分自身、つまりPersonクラスに対してattr_accessorメソッドを呼びます。 このメソッドが呼ばれると、ゲッタとセッタ二つのメソッドが自動的に生成されます。ほぼ同じ処理を手動で書くと、define_methodを呼び出すことでこのように書けます。
  • #22: これがRubyの特徴的なところで、この言語においては全てがオブジェクトとして表現されています。全てというのは、つまり、クラスも含みます。 定数AにClassクラスの新しいインスタンスを代入することで新しいクラスが作れるし、クラスAに対してdefine_methodメソッドを呼ぶことで新しいメソッドを定義できます。
  • #23: このattr_accesorメソッドのような、クラス定義内で使えるメソッドのことをRubyでは「マクロ」と呼んだりします。 Scala等のコンパイル言語でマクロと言うと、コンパイル時に評価されてASTいじったりする機能のことを指すのでここはRuby文化の特殊なところですね。そもそもRubyにはコンパイル時という概念がないので、他の言語だとマクロで実現するような機能をマクロって読んでるんじゃないかと思います。
  • #24: Scalaでアクセサメソッドを定義しようと思ったら、valやvarキーワードという言語組み込みの機能を使うことになります。これって頑張ればマクロで実現可能なのかというと、たぶん無理な気がします 必要な機能セットをあらかじめsyntaxに含める必要があるScalaと、クラスを動的に操作可能にすることで単なるメソッドで実現可能にするRubyという対比ができそうですね。
  • #25: 最初の例に戻りましょう。Rubyにおいてはクラス定義も動的に実行されるため、Personの定義時にStructのインスタンスが作成され、継承元として指定されます。
  • #26: アクセサの例ではメソッドを動的に定義していましたが、Rubyにおいてはクラスそのものも同様に動的生成できます。 Structにアクセサ名を渡してnewすると、先ほどの単純な例で示したのと同じようなクラスが自動生成されます。 このクラスを継承することで、適切なコンストラクタとアクセサを使えるようになってメデタシメデタシとなります。
  • #27: というわけで、クラス定義を例にしてRubyが動的にクラスを操作可能な言語だということを見てきました。
  • #28: OOの話をしたので次に関数について比べてみます。 ScalaとRubyはどちらも関数を値として扱ったり、インラインで関数を作るための機能を持っています。 変数に束縛した関数を呼ぶ場合、Scalaの場合は通常の関数と同じように呼べますがRubyの場合は関数と値が区別されていて、callメソッドまたはそのエイリアスを呼ぶ必要があります。ドットの後に括弧書く記法は最近のバージョンで入ったみたいなんですが、なんかすごいですねこれ……
  • #29: 関数を値として扱うときの方針は、関数型言語の中でも判断がわかれています。たとえばSchemeやJavaScriptのような言語だと、関数名を書けばその関数を値として取得できて、引数を渡せばその関数を呼べるというシンプルで一貫性のある仕様になっています。いっぽうCommonLispだと関数と値の名前空間が分かれていて、関数を値にしたい、あるいは値を関数として呼びたいときは特殊な記法を使う必要があります。 一般的に、利便性を重視しようとするとルールを複雑にする必要が出てくるようです。Scalaでも、名前空間こそ同じですが関数名書いただけだと値として扱ってくれずに_つける必要があったり、このへんは工夫のしどころみたいです。
  • #30: 関数を値として取得する方法についてもう少し詳しく見てみます。 まずはScalaの事例。fooというIntをとってStringを返す1引数の関数について考えてみます。 Scalaにおいては関数と値の名前空間は同一ですが、f = fooのように、直接関数名を書いてもScalaは値として扱ってくれません。 foo _ のように、識別子の後ろにアンスコをつけることで「その関数を値として取得する」という指定ができます。 また、別の関数にfooを渡す場合については、名前を指定するだけでもいけます。 匿名関数を作る場合は、このようにファットアローで書きます。Scalaの関数呼び出しにおいては、1引数の場合丸括弧のかわりに波括弧も使えます。関数を渡す場合波括弧を使うのが慣習になっているようです。 また、アンダースコアを使うことで「第一引数のtoStringを呼んだ結果」を_.toStringと書けて便利というのもあります。
  • #31: Rubyにおいては、関数を値として取得する場合はmethodメソッドに対象の名前を渡してやる必要があります。実際のコードではあまりこういうことはせず、対象を呼び出す匿名関数を作るケースのほうが一般的だと思いますが。 関数を受け取る関数を書く場合、通常のオブジェクトとして受け取る方法とブロックとして受け取る方法があります。 ブロックというのは関数呼び出し時に一つだけ渡せるコードブロックのことで、呼び出しの後に波括弧でくくった内容が匿名関数として渡せます。値をブロックとして渡したいときは引数に&をつけます。
  • #32: Rubyブロック引数の特徴として、関数以外の値も渡せることが挙げられます。 このコードは数値の配列を文字列の配列にマップしていますが、ここでmapの引数として渡している&:to_sというのはScalaで言うところの_.toString相当です。 RubyにおいてのコロンはScalaのシングルクオート相当で、Symbolリテラルになっています。 さて、シンボルをブロックとして与えると何が起こるんでしょう。実はRubyでは、ブロックとして渡した値に対してto_procメソッドを呼んで、その結果を使用します。Symbolのto_procは、「引数を一つとって、そのオブジェクトに対して自分と同名のメソッドを呼ぶ」という関数を返すように定義されているため、このようなことが可能になってます。ちょっとわかりにくいですが、:to_sというSymbolをto_procすると、引数のto_procを呼ぶような関数が生成されるということですね。
  • #33: 次にコレクションについて見てみます。 Rubyの場合は連想配列と配列のリテラルがあります。 いっぽう、Scalaの場合はTupleのリテラルがあります。 最初Scalaに入った時は、これが不思議でした。よく使うコレクションにリテラルが用意されてなくて、Seq()とかMap()とか書かなきゃいけないのはなんでだろうと。
  • #34: ここでScalaの標準コレクションを見てみましょう。値を列挙できるTraversable型が元になって、不変と可変それぞれに用途別の細分化されたデータ構造が準備されています。 さて、今度はRubyのコレクションを見てみましょう。 対応関係はこんなかんじです。 あ、TupleはArrayで代用されます。 ScalaにTuple以外のコレクションリテラルがないのは、標準的に使われる唯一の配列型やハッシュ型というのがないせいなんでしょうね。
  • #35: Rubyのライブラリ設計についてよく言われるのが、「大クラス主義」です。Arrayクラスはスタックのようなpush/pop操作、キューのようなshift/pop操作、あるいは任意の位置に要素を挿入したり、インデクスでアクセスしたり列挙したりできて、あと異なる型の値を入れてタプル的にも使われています。実際のところ、Ruby標準ライブラリにはスタックやリンクドリストというクラスはなくて、全部アレイで済ますことになっている。 同様に連想配列についてもミュータブルなハッシュ実装がひとつあるだけで、キーとバリューの組み合わせが必要なところではどこでもこれが使われています。
  • #36: RubyとScalaのコレクション設計で特筆すべきは、型変換の問題です。Rubyにおいては少数の大きいコレクションクラスしかないので、特に複雑なことはありません。たいていのmapメソッドはArrayを返します。
  • #37: これがScalaになると話が違います。IteratorをmapするとIteratorになるし、ListをmapするとListが返ります。mapの返り値がコレクションごとに異なるというだけなら、がんばって各クラスごとに特殊化したmapを書いてもいいかもしれませんが、BitSetの中身をIntにマップすると返り値はBitSet、StringにマップするとなんとSortedSetになります。 Scalaにおいては、これらの処理をDRYに書きつつ静的に適切な型が選ばれるように、CanBuildFrom型のimplicit引数が使われています。 このかっこいいmapメソッドのシグネチャを御覧ください。静的に解決できることは極力静的に解決するために、型の力を最大限使おうというのが見て取れます。
  • #38: さて、次に既存クラスの拡張についてです。 Scalaにおいては、implicit conversionであるクラスを拡張する別のクラスに変換してメソッドを追加したり、あるいは既存クラスの挙動をサブクラス化で変えるなどができます。
  • #39: しかしRubyの場合は動的にクラスを変更できるので、Scalaよりかなり過激なことが出来ます。 できることの一例としては、既存クラスのメソッドを別のものに差し替えるとか、特異メソッドとかシングルトンメソッドと呼ばれる仕組みで特定のオブジェクトのみメソッドを上書きするということが可能です。 また、includeという機構を使うことでクラスの継承関係に新しいクラスを差し込んだりすることもできます。 既存クラスをそんなダイナミックに書き換えてよく事故らないなという感じですけど、意外と大丈夫です。なぜか。特にRuby on Railsを使うと、文字列や数値といった標準型にも大量の便利メソッドが追加されたりしてダイナミックな感じです。 既存クラスを書き換えることはモンキーパッチングなどと呼ばれています。ライブラリにバグが出る場合にメソッド書き換えて逃げるとか、テスト時だけダミーのメソッドに差し替えるとかできるのではまるとかなり便利です。 あと、refinementsという特定のスコープだけメソッドの書き換えを有効にする仕組みが最近入りました。
  • #40: 最後に、値が存在しないという事象をどう扱うかについて説明します。Scalaの場合はOptionですね。Rubyの場合はみんな大好きヌルを使います。Rubyにおいてはニルという呼び方なんですが、この値はfalseと合わせて、if文においては偽と判定されます。なのでobjがnilでないときだけメソッドを呼ぶにはif文の中にobjを入れるだけなので簡単ですね。 こういうパターンはあまりによく使うので、Railsで使われてる拡張ライブラリであるActiveSupportではtryメソッドが導入されました。呼びたいメソッド名を渡すことで、nilの場合は何もせず、そうじゃなかったらメソッドを実際に呼ぶというやつです。Rubyではこんなかんじなので、nilに対してメソッドを呼んでNoMethodErrorになる事例が頻発してます。まあ動的言語だと色いろあるよね…… 安全性はともかく、Scalaよりシンプルに書けるというメリットはあります。
  • #41: というわけで、Scalaとの比較を通してRuby言語の機能を紹介していきました。 なんでも動的に解決するRubyとコンパイル時にすごく色々やるScala、やり方はぜんぜん違うんですけど、生産性を高めて楽しくプログラミングしようというところは似てると思います!! 今日見てきたように、ある問題を解決するための方法は複数あって、どれを選択するかが言語の個性になっています。他の言語を学ぶことによって色々な方法を知るのはおもしろいのでいろんな言語をやりましょう。