SlideShare a Scribd company logo
Getting started with

Ruby Topic Maps
Benjamin Bock



Third International Conference on Topic Maps Research and Applications
Tutorials@TMRA Leipzig, 2007-10-10
Why Ruby?

interpreted, object-oriented
  programming
features procedural and
  functional paradigm
everything is an object

dynamic and (but) strong typed
                                 2
What about Rails?

Model-View-Controller

Convention over Configuration

Optimized for programmer
 happiness and productivity

                                3
… and Ruby Topic Maps?

Web 2.0 is about integration

Ruby and Ruby on Rails are big
 players there

Topic Maps nonexisting in the
 Ruby world
                                 4
Schedule

Introduction
Software distribution
Programming Ruby
Ruby Topic Maps
Rails Basics
Using RTM in Rails

                         5
Command line tool
irb: Interactive RuBy

Windows:
  Click start -> run -> “cmd” -> “irb”
Mac OS X:
  Start the Terminal -> type “irb”
Linux:
  Open a shell -> type “irb”

That’s what you get:
irb(main):001:0>
                                         6
Calculator

irb(main):001:0> 1+2

irb(main):002:0> 3*4

irb(main):003:0> 5**3

irb(main):004:0> Math.sqrt(81)

                                 7
Simple Types

# comment until end of line
quot;Stringquot;
1 # number
1.0 # floating point number
1_000_000_000_000 # BigNum
:symbol # these are important!
true, false, self, nil
                                 8
Even More Types

[1,2,3] # Array
{ :key => quot;valuequot; } # Hash
/regular expression/
(1..10) # exclusive Range
(1...10) # inclusive Rage
# Files are also basic types,
# but what does that mean?
                                9
Numbers

123 1_234 123.45 1.2e-3
0xffff (hex) 0b01011 (binary)
  0377 (octal)
?a       # ASCII character
?C-a    # Control-a
?M-a    # Meta-a
?M-C-a # Meta-Control-a
                                10
Strings
'no interpolation'
quot;#{interpolation}, and backslashesnquot;
%q(no interpolation)
%Q(interpolation and backslashes)
%(interpolation and backslashes)
`echo command interpretation with
  interpolation and backslashes`
%x(echo command interpretation with
  interpolation and backslashes)

`ls` # returns output of system command ls
                                             11
Methods
def hello
  puts quot;helloquot;
end

def salute(who)
  puts quot;Hello #{who}quot;
end

def salute(who=quot;worldquot;)
  puts quot;Hello #{who.capitalize}quot;
end
                                   12
Method Invocation
method
obj.method
Class::method

# keyword parametres: one argument for def method(hash_arg):
method(key1 => val1, key2 => val2)

becomes: method(arg1, arg2, arg3):
method(arg1, *[arg2, arg3])

#as ugly as you want it to be:
method(arg1, key1 => val1, key2 => val2, *splat_arg) #{ block }

# A bit more formal:
invocation := [receiver ('::' | '.')] name [ parameters ] [ block ]
parameters := ( [param]* [, hashlist] [*array] [&aProc] )
block      := { blockbody } | do blockbody end


                                                                      13
Everything is an Object

nil.class
true.object_id
2.75.ceil
5.times do # this a preview,
  details later
  puts quot;I like Ruby!quot;
end
                               14
Everybody is valuable
# ... and everything has a value

# often no quot;returnquot; statements needed
def value
  5
end
x = value # x = 5
y = if 1 != 2 # even if has a value
  quot;rightquot;
else
  quot;wrongquot;
end
# y == quot;rightquot;
                                        15
But what if ...
if condition [then]
  # true block
elsif other_condition # not elseif!
  # second true block
else
  # last chance
end

# also:
z = condition ? true_value : false_value
                                           16
Can you tell me the
truth?
# Yes, it's 42

if 0 then
 quot;this is the casequot;
else
 quot;but this will not happenquot;
end

# Only false and nil are not true!
# That's handy for == nil checks.
                                     17
the case is as follows
case my_var
  when quot;hiquot;, quot;helloquot;, quot;halloquot;, quot;salutquot;
    puts quot;it was an greetingquot;
  when String
    puts quot;it was a string...quot;
  when (1..100)
    puts quot;A number between 0 and 100quot;
  when Numeric
    puts quot;A number not in the range abovequot;
  else
    puts quot;What did you give me here?quot;
  end
end
                                             18
Back to the Question
# there are other conditionals

return false if you_dont_like_to_answer

unless you_are_already_asleep
  i_will_go_on
end

# this is not a loop!

                                          19
Iteration     Iteration   Iteration   Iteration




5.times { |x| puts x }
[quot;alicequot;, quot;bobquot;].each do |name|
  puts quot;Hello #{name}quot;
end
list = [6,7,2,82,12]
for x in list do
  puts x
end
                                                  20
go_on until audience.asleep?

loop do
  body
end

{while,until} bool-expr [do]
 body
end

begin
 body
end {while,until} bool-expr
# we have: break, next,redo, retry

                                     21
Blocks (a.k.a. Closures)
search_engines =
%w[Google Yahoo MSN].map do |engine|
  quot;http://www.quot; + engine.downcase +
  quot;.comquot;
end

%w[abcde fghi jkl mn op q].sort_by { |
  w|
  w.size
}
                                         22
Object Oriented Constructs

$global_variable
module SomeThingLikePackageInJava
  class SameLikeJava < SuperClass
    @instance_variable
    @@class_variable
    def initialize()
      puts quot;I am the constructorquot;
    end
    def method(param, optional_param=quot;defaultquot;)
      quot;This String is returned, even without return
   statementquot;
    end
  end
end
SomeModule::CONSTANT
                                                      23
Meaningful Method Names
# usage: some_object.valid?class Person
class Person
  def name; @name; end
  def name=(new_name)
    @name = new_name
  end
  def valid?
    return true unless name && name.empty?
    false
  end
end
class Person # almost the same
  attr_accessor :name
  def valid?; name && ! name.empty?; end
end
p = Person.new
person.valid?
person.name = quot;Benjaminquot;
person.valid?
                                             24
Only one aunt may die
# single inheritance only

# alternative model: mixins

class MyArray
  include Enumerable
  def each
    # your iterator here
  end
end
# Enumerable provides:
all? any? collect detect each_with_index entries find
   find_all grep group_by include? index_by inject map max
   member? min partition reject select sort sort_by sum to_a
   to_set zip
                                                               25
Ruby is flexible

class Numeric
  def plus(x)
    self.+(x)
  end
end

y = 5.plus 6
# y is now equal to 11
                         26
Redefining Methods
warn(quot;Don't try this at home or at allquot;)

class Fixnum
  def +( other )
    self - other
  end
end

5+3
# => 2
                                           27
Introspection
# Tell me what you are
5.class
quot;qwertyquot;.class

# Tell me what you do
[1,2,3].methods

# this is how I got the list above
Enumerable.instance_methods.sort.join(quot; quot;)

# Would you? Please...
some_variable.respond_to? :each

                                             28
Missing Methods
# id is the name of the method called, the * syntax
  collects
# all the arguments in an array named 'arguments'
def method_missing( id, *arguments )
  puts quot;Method #{id} was called, but not found. It has
  quot;+
       quot;these arguments: #{arguments.join(quot;, quot;)}quot;
end

__ :a, :b, 10
# => Method __ was called, but not found. It has these
# arguments: a, b, 10


                                                         29
eval is evil...
class Klass
  def initialize
    @secret = 99
  end
end
k = Klass.new
k.instance_eval { @secret } # => 99

# generally:
eval(quot;some arbitrary ruby codequot;)
                                      30
...but may be really helpful
eval(string [, binding [, filename [,lineno]]]) => obj
mod.class_eval(string [, filename [, lineno]]) => obj

# there are many blocks like this in the RTM source
  code
module_eval(<<-EOS,
  quot;(__PSEUDO_FILENAME_FOR_TRACES__)quot;, 1)
  def #{method_name_variable}
    some custom method using #{more} #{variables}
  end
EOS



                                                         31
Something (not so) exceptional

begin
  # some code
  # may raise an exception
rescue ExceptionType => ex
  # exception handler
else
  # no exception was raised
ensure
  # this stuff is done for sure
end

raise Exception, quot;Messagequot;

                                  32
Things we do not cover here

alias
here docs
regex details
access restriction
predefined variables: $!, $@, $: ...
backslash constructions: n t
and some other
stuff we do
not need
today
                                       33
Sources
http://www.ruby-lang.org/en/about/

http://www.ruby-lang.org/en/documentation/ruby-from-
  other-languages/

http://www.zenspider.com/Languages/Ruby/QuickRef.html

http://www.ruby-doc.org/core/




                                                        34
Break
require 'timeout'
begin
  status = Timeout::timeout(30.minutes) do
    ingestion = Thread.start do
      loop { get_coffee; drink; sleep(30); }
    end
    chat = Thread.start do
      loop { sleep(15); talk; listen; smile; }
    end
  end
rescue Timeout::Error
  puts quot;Let's get back to workquot;
end
                                                 35
Demo session



# Seeing is believing… :-)



                             36
# loading the Ruby Topic Maps library
# in a script or in environment.rb
require 'rtm'

# a new module called RTM will be
# loaded into the default namespace

# To get direct access to constants like
# PSI, a hash of TMDM subject indicators
# use
include RTM

                                           37
# Connecting to a back end
# Memory
RTM.connect
# File database, default is tmdm.sqlite3
RTM.connect_sqlite3
# Custom database file
RTM.connect_sqlite3(quot;filename.dbquot;)
# Standard MySQL database
RTM.connect_mysql(quot;database_namequot;,
  quot;user_namequot;, quot;passwordquot;, quot;hostquot;)
                                           38
# At first time use, we have to generate
  all the tables in the database
RTM.generate_database

# for now, we use memory database
RTM.connect
# or
RTM.connect_memory

# enable SQL statement logging
RTM.log
# defaults to STDOUT, configurable as Logger
                                               39
Ruby on Rails


# Get on the Train!
# Can I see your ticket, please?




                                   40
Hands-on



# Now, it’s your turn… :-P
                      (again)




                             41
Fin
begin
 puts quot;Questions?quot;
 x = gets
 puts response_to(x)
end until x =~ /(no|exit|quit)/i

puts quot;Thank you very much?quot;
                                   42

More Related Content

Ruby Topic Maps Tutorial (2007-10-10)

  • 1. Getting started with Ruby Topic Maps Benjamin Bock Third International Conference on Topic Maps Research and Applications Tutorials@TMRA Leipzig, 2007-10-10
  • 2. Why Ruby? interpreted, object-oriented programming features procedural and functional paradigm everything is an object dynamic and (but) strong typed 2
  • 3. What about Rails? Model-View-Controller Convention over Configuration Optimized for programmer happiness and productivity 3
  • 4. … and Ruby Topic Maps? Web 2.0 is about integration Ruby and Ruby on Rails are big players there Topic Maps nonexisting in the Ruby world 4
  • 5. Schedule Introduction Software distribution Programming Ruby Ruby Topic Maps Rails Basics Using RTM in Rails 5
  • 6. Command line tool irb: Interactive RuBy Windows: Click start -> run -> “cmd” -> “irb” Mac OS X: Start the Terminal -> type “irb” Linux: Open a shell -> type “irb” That’s what you get: irb(main):001:0> 6
  • 8. Simple Types # comment until end of line quot;Stringquot; 1 # number 1.0 # floating point number 1_000_000_000_000 # BigNum :symbol # these are important! true, false, self, nil 8
  • 9. Even More Types [1,2,3] # Array { :key => quot;valuequot; } # Hash /regular expression/ (1..10) # exclusive Range (1...10) # inclusive Rage # Files are also basic types, # but what does that mean? 9
  • 10. Numbers 123 1_234 123.45 1.2e-3 0xffff (hex) 0b01011 (binary) 0377 (octal) ?a # ASCII character ?C-a # Control-a ?M-a # Meta-a ?M-C-a # Meta-Control-a 10
  • 11. Strings 'no interpolation' quot;#{interpolation}, and backslashesnquot; %q(no interpolation) %Q(interpolation and backslashes) %(interpolation and backslashes) `echo command interpretation with interpolation and backslashes` %x(echo command interpretation with interpolation and backslashes) `ls` # returns output of system command ls 11
  • 12. Methods def hello puts quot;helloquot; end def salute(who) puts quot;Hello #{who}quot; end def salute(who=quot;worldquot;) puts quot;Hello #{who.capitalize}quot; end 12
  • 13. Method Invocation method obj.method Class::method # keyword parametres: one argument for def method(hash_arg): method(key1 => val1, key2 => val2) becomes: method(arg1, arg2, arg3): method(arg1, *[arg2, arg3]) #as ugly as you want it to be: method(arg1, key1 => val1, key2 => val2, *splat_arg) #{ block } # A bit more formal: invocation := [receiver ('::' | '.')] name [ parameters ] [ block ] parameters := ( [param]* [, hashlist] [*array] [&aProc] ) block := { blockbody } | do blockbody end 13
  • 14. Everything is an Object nil.class true.object_id 2.75.ceil 5.times do # this a preview, details later puts quot;I like Ruby!quot; end 14
  • 15. Everybody is valuable # ... and everything has a value # often no quot;returnquot; statements needed def value 5 end x = value # x = 5 y = if 1 != 2 # even if has a value quot;rightquot; else quot;wrongquot; end # y == quot;rightquot; 15
  • 16. But what if ... if condition [then] # true block elsif other_condition # not elseif! # second true block else # last chance end # also: z = condition ? true_value : false_value 16
  • 17. Can you tell me the truth? # Yes, it's 42 if 0 then quot;this is the casequot; else quot;but this will not happenquot; end # Only false and nil are not true! # That's handy for == nil checks. 17
  • 18. the case is as follows case my_var when quot;hiquot;, quot;helloquot;, quot;halloquot;, quot;salutquot; puts quot;it was an greetingquot; when String puts quot;it was a string...quot; when (1..100) puts quot;A number between 0 and 100quot; when Numeric puts quot;A number not in the range abovequot; else puts quot;What did you give me here?quot; end end 18
  • 19. Back to the Question # there are other conditionals return false if you_dont_like_to_answer unless you_are_already_asleep i_will_go_on end # this is not a loop! 19
  • 20. Iteration Iteration Iteration Iteration 5.times { |x| puts x } [quot;alicequot;, quot;bobquot;].each do |name| puts quot;Hello #{name}quot; end list = [6,7,2,82,12] for x in list do puts x end 20
  • 21. go_on until audience.asleep? loop do body end {while,until} bool-expr [do] body end begin body end {while,until} bool-expr # we have: break, next,redo, retry 21
  • 22. Blocks (a.k.a. Closures) search_engines = %w[Google Yahoo MSN].map do |engine| quot;http://www.quot; + engine.downcase + quot;.comquot; end %w[abcde fghi jkl mn op q].sort_by { | w| w.size } 22
  • 23. Object Oriented Constructs $global_variable module SomeThingLikePackageInJava class SameLikeJava < SuperClass @instance_variable @@class_variable def initialize() puts quot;I am the constructorquot; end def method(param, optional_param=quot;defaultquot;) quot;This String is returned, even without return statementquot; end end end SomeModule::CONSTANT 23
  • 24. Meaningful Method Names # usage: some_object.valid?class Person class Person def name; @name; end def name=(new_name) @name = new_name end def valid? return true unless name && name.empty? false end end class Person # almost the same attr_accessor :name def valid?; name && ! name.empty?; end end p = Person.new person.valid? person.name = quot;Benjaminquot; person.valid? 24
  • 25. Only one aunt may die # single inheritance only # alternative model: mixins class MyArray include Enumerable def each # your iterator here end end # Enumerable provides: all? any? collect detect each_with_index entries find find_all grep group_by include? index_by inject map max member? min partition reject select sort sort_by sum to_a to_set zip 25
  • 26. Ruby is flexible class Numeric def plus(x) self.+(x) end end y = 5.plus 6 # y is now equal to 11 26
  • 27. Redefining Methods warn(quot;Don't try this at home or at allquot;) class Fixnum def +( other ) self - other end end 5+3 # => 2 27
  • 28. Introspection # Tell me what you are 5.class quot;qwertyquot;.class # Tell me what you do [1,2,3].methods # this is how I got the list above Enumerable.instance_methods.sort.join(quot; quot;) # Would you? Please... some_variable.respond_to? :each 28
  • 29. Missing Methods # id is the name of the method called, the * syntax collects # all the arguments in an array named 'arguments' def method_missing( id, *arguments ) puts quot;Method #{id} was called, but not found. It has quot;+ quot;these arguments: #{arguments.join(quot;, quot;)}quot; end __ :a, :b, 10 # => Method __ was called, but not found. It has these # arguments: a, b, 10 29
  • 30. eval is evil... class Klass def initialize @secret = 99 end end k = Klass.new k.instance_eval { @secret } # => 99 # generally: eval(quot;some arbitrary ruby codequot;) 30
  • 31. ...but may be really helpful eval(string [, binding [, filename [,lineno]]]) => obj mod.class_eval(string [, filename [, lineno]]) => obj # there are many blocks like this in the RTM source code module_eval(<<-EOS, quot;(__PSEUDO_FILENAME_FOR_TRACES__)quot;, 1) def #{method_name_variable} some custom method using #{more} #{variables} end EOS 31
  • 32. Something (not so) exceptional begin # some code # may raise an exception rescue ExceptionType => ex # exception handler else # no exception was raised ensure # this stuff is done for sure end raise Exception, quot;Messagequot; 32
  • 33. Things we do not cover here alias here docs regex details access restriction predefined variables: $!, $@, $: ... backslash constructions: n t and some other stuff we do not need today 33
  • 35. Break require 'timeout' begin status = Timeout::timeout(30.minutes) do ingestion = Thread.start do loop { get_coffee; drink; sleep(30); } end chat = Thread.start do loop { sleep(15); talk; listen; smile; } end end rescue Timeout::Error puts quot;Let's get back to workquot; end 35
  • 36. Demo session # Seeing is believing… :-) 36
  • 37. # loading the Ruby Topic Maps library # in a script or in environment.rb require 'rtm' # a new module called RTM will be # loaded into the default namespace # To get direct access to constants like # PSI, a hash of TMDM subject indicators # use include RTM 37
  • 38. # Connecting to a back end # Memory RTM.connect # File database, default is tmdm.sqlite3 RTM.connect_sqlite3 # Custom database file RTM.connect_sqlite3(quot;filename.dbquot;) # Standard MySQL database RTM.connect_mysql(quot;database_namequot;, quot;user_namequot;, quot;passwordquot;, quot;hostquot;) 38
  • 39. # At first time use, we have to generate all the tables in the database RTM.generate_database # for now, we use memory database RTM.connect # or RTM.connect_memory # enable SQL statement logging RTM.log # defaults to STDOUT, configurable as Logger 39
  • 40. Ruby on Rails # Get on the Train! # Can I see your ticket, please? 40
  • 41. Hands-on # Now, it’s your turn… :-P (again) 41
  • 42. Fin begin puts quot;Questions?quot; x = gets puts response_to(x) end until x =~ /(no|exit|quit)/i puts quot;Thank you very much?quot; 42