RSS Log in
 

Reading notes from the fifth chapter (The default object (self), scope, and visibility) of The Well-Grounded Rubyist by David A. Black.

 

Self

puts "Top Level"
puts "self is #{self}"

class C
    puts "Class definition block:"
    puts "self is #{self}"

    def self.x
        puts "Class method x of class C"
        puts "self is #{self}"
    end

    def m
        puts "Instance method m of class C:"
        puts "self is #{self}"
    end
end

C.x
c = C.new
c.m

Output:

Top Level
self is main
Class definition block:
self is C
Class method x of class C
self is C
Instance method m of class C:

self is #<C:0x6172c8>

Note: #<C:0x6172c8> is the hexadecimal number representing the memory-location reference of the object instance. 

 

Implicit self

class Person
    attr_accessor :first_name, :middle_name, :last_name

    def whole_name
        n = first_name + " "
        n << "#{middle_name} " if middle_name
        n << last_name
    end
end

tbf = Person.new

tbf.first_name = "The"
tbf.last_name = "Frog"

puts "Name: #{tbf.whole_name}"

tbf.middle_name = "Boolean"
puts "Full Name: #{tbf.whole_name}"

Output:

Name: The Frog
Full Name: The Boolean Frog

 

Global variables

$gvar = "I'm global!"

class C
    def print_global_var
        puts $gvar
    end
end

c = C.new
c.print_global_var

Global variables start with $.

 

Built-in global variables

The friendly names for the built-in global variables can be found in the English.rb file (in the “lib\ruby\1.9.1” folder of the directory where Ruby is installed).

Some examples together with the explanation found in the English.rb file:

 

GVAR Description Friendly Name

$!

The exception object passed to raise.

$ERROR_INFO

$@

The stack backtrace generated by the last exception.

$ERROR_POSITION

$;

The default separator pattern used by String.split.

$FS or $FIELD_SEPARATOR

$,

The separator string output between the parameters to methods such as Kernel.print and Array.join. Defaults to nil, which adds no text.

$OFS

$OUTPUT_FIELD_SEPARATOR

$/

The input record separator (newline by default). This is the value that routines such as Kernel.gets use to determine record boundaries. If set to nil, gets will read the entire file.

$RS

$INPUT_RECORD_SEPARATOR

$\

The string appended to the output of every call to methods such as Kernel.print and IO.write. The default value is nil.

$ORS

$OUTPUT_RECORD_SEPARATOR

$.

The number of the last line read from the current input file.

$INPUT_LINE_NUMBER or $NR

$_

The last line read by Kernel.gets or Kernel.readline. Many string-related functions in the Kernel module operate on $_ by default. The variable is local to the current scope.

$LAST_READ_LINE

$>

The destination of output for Kernel.print and Kernel.printf. The default value is $stdout.

$DEFAULT_OUTPUT

$<

An object that provides access to the concatenation of the contents of all the files given as command-line arguments.

$DEFAULT_INPUT

$$

The process number of the program being executed. Read only.

$PID or $PROCESS_ID

$?

The exit status of the last child process to terminate. Read only.

$CHILD_STATUS

$~

A MatchData object that encapsulates the results of a successful pattern match. The variables $&, $`, $', and $1 to $9 are all derived from $~. Assigning to $~ changes the values of these derived variables.  This variable is local to the current scope.

$LAST_MATCH_INFO

$*

An array of strings containing the command-line options from the invocation of the program. Options used by the Ruby interpreter will have been removed. Read only. Also known simply as ARGV.

$ARGV

$&

The string matched by the last successful pattern match. This variable is local to the current scope. Read only.

$MATCH

$`

The string preceding the match in the last successful pattern match. This variable is local to the current scope. Read only.

$PREMATCH

$'

The string following the match in the last successful pattern match. This variable is local to the current scope. Read only.

$POSTMATCH

$+

The contents of the highest-numbered group matched in the last successful pattern match. Thus, in "cat" =~ /(c|a)(t|z)/, $+ will be set to "t".  This variable is local to the current scope. Read only.

$LAST_PAREN_MATCH

 

Constant Lookup

Relative Path
module M
    class C
        class D
            module N
                X = 1
            end
        end

        puts D::N::X
    end
end

 

Constant Path
module S
  # Name clashes with name of built-in String class
  class String
      attr_accessor :count

      def initialize(count)
          @count = count
      end
  end

  # Use :: to refer to the top level (in this case the built-in) String type.
  puts ::String.new("TEST")
end

str = S::String.new(10)
puts str.count

Output:

TEST

10

 

Class variables

Class variables start with @@ and are only visible to the class itself and instances of the class.

Example:

class Population
    @@countries = []
    @@count = {} # key-value pair dictionary

    attr_reader :country

    def self.total_count
        @@total_count ||= 0
    end

    def self.total_count= (n)
        @total_count = n
    end

    def self.add_country(country)
        unless @@countries.include?(country)
            @@countries << country
            @@count[country] = 0
        end
    end

    def initialize(country)
        if @@countries.include?(country)
            puts "Incrementing #{country} population..."
            @country = country
            @@count[country] += 1
            self.class.total_count += 1
        else
            raise "No such country as '#{country}'"
        end
    end

    def find_countrymen
        @@count[self.country]
    end
end


Population.add_country("UK")
Population.add_country("France")

u = Population.new("UK")
f = Population.new("France")
u2 = Population.new("UK")

puts "Counting population of #{u2.country} (same country as u2)..."
puts "There are #{u2.find_countrymen} people."

puts "Counting total population..."
puts "There are #{Population.total_count} people."

x = Population.new("Lalaland")

Output:

Incrementing France population...
Incrementing UK population...
Counting population of UK (same country as u2)...
There are 2 people.
Counting total population...
There are 3 people.
: No such country as 'Lalaland' (RuntimeError)

The code snippet above is effectively similar to Listing 5.7 in The Well-Grounded Rubyist with only the class and method names changed.

 

Private Methods

To make a method private, simply mark it as private.

class Dictionary
    attr_reader :translation

    def translation= (translation)
        @translation = translation
    end

    def lookup(word)
        translate(word)
    end

    def translate(word)
        if word == "Hello"
            self.translation = "Bonjour"
        else
            @translation = "Not in the dictionary"
        end
    end

    private :translation=, :translate
end

dictionary = Dictionary.new

dictionary.lookup("Hello")
puts "Hello is #{dictionary.translation}."

dictionary.lookup("Hola")
puts "Hola is #{dictionary.translation}."

 

Calling the private methods out-of scope results in a fatal error:

dictionary.translate("Hello")

Output:

private method `translate' called for #<Dictionary:0x436e90> (NoMethodError)

dictionary.translation = "TEST"

Output:

private method `translation=' called for #<Dictionary:0x24b6e50> (NoMethodError)

 

Protected Methods

To make a method protected, simply mark it as protected.

Note that a protected method can be called by the object itself and also by another instance of the same class or subclass.

class Person
    def initialize(age)
        @age = age
    end

    def age
        @age
    end

    def compare(other)
        if other.age > age
            puts "The other person is older."
        else
            puts "The other person is the same age or younger."
        end
    end

    protected :age
end

p1 = Person.new(20)
p2 = Person.new(50)

p1.compare(p2)

 

Kernel built-in methods

ruby -e 'print Kernel.private_instance_methods(false).sort'

Output:

[:Array, :Complex, :Float, :Integer, :Rational, :String, :__callee__, :__method__, :`, :abort, :at_exit, :autoload, :autoload?, :binding, :block_given?, :caller, :catch, :eval, :exec, :exit, :exit!, :fail, :fork, :format, :gem, :gem_original_require, :gets, :global_variables, :initialize_copy, :iterator?, :lambda, :load, :local_variables, :loop, :open, :p, :print, :printf, :proc, :putc, :puts, :raise, :rand, :readline, :readlines, :remove_instance_variable, :require, :require_relative, :select, :set_trace_func, :sleep, :spawn, :sprintf, :srand, :syscall, :system, :test, :throw, :trace_var, :trap, :untrace_var, :warn]


Comments are closed
© Copyright 2012 TheBooleanFrog Powered by: BlogEngine.NET|Credits|Subscribe via RSS

Follow

twitter linkedin linkedin rss

TheBooleanFrog

Programming sticky notes and other distractions...