Ruby metaprogramming online tutorial
The above article does refer to this but I'll post it for clarity:
http://viewsourcecode.org/why/hacking/seeingMetaclassesClearly.html
Why is it important to learn about metaprogramming and eigenclasses in Ruby?
What benefits are gained when using metaprogramming?
You can create more expressive APIs than without it (for example ActiveRecord uses metaprogramming to define accessor methods based on a table's column names, so you can write things like
person.age
instead of something likeperson.read_attribute("age")
, whereperson
is an active record object and thepeople
table has a column calledage
) and you can accomplish some things with significantly less code than you otherwise would.What is an eigenclass and how is it different from a singleton?
The terms "eigenclass" and "singleton class" are used interchangeably in the context of ruby.
In what situations is using metaprogramming common?
In situations where you'd otherwise have a lot of boiler plate code or when creating DSLs.
Example of use case 1:
Instead of writing something boiler-plate code like this:
class Foo
def bar
@bar
end
def bar=(b)
@bar = b
end
def baz
@baz
end
def baz=(b)
@baz = b
end
endYou can write this much shorter code using the metaprogramming method
attr_accessor
, which automatically defines getter and setter methods with names based on the arguments you give it:class Foo
attr_accessor :foo, :bar
endIf
attr_accessor
didn't already exist in the standard library, you could define it yourself like this (to give you an idea what metaprogramming in ruby looks like):class Module
def attr_accessor(*variable_names)
variable_names.each do |variable_name|
define_method( variable_name ) do
instance_variable_get( "@#{ variable_name }" )
end
define_method( "#{ variable_name }=" ) do |value|
instance_variable_set( "@#{ variable_name }", value)
end
end
endend
What ethical implications are there around using code to modify the behaviour of other code, especially code which is not your own?
None.
Very simple DSL in Ruby
There're many different ways in which you can implement something like this. To keep it simple, you can just evaluate the block within a new Screen
object and return the result.
class Screen
attr_reader :texts
def initialize
@texts = []
end
def label(hash)
# Validation + check for other keys
texts << hash[:text]
end
def to_s
texts.join
end
def self.write(&block)
raise "No block given" unless block_given?
Screen.new.tap do |s|
s.instance_eval(&block)
end
end
end
text = Screen.write do
label text: 'Something'
label text: 'stupid'
end
p "Rendered: #{text}"
How does RoR's magic namespace resolution work?
Rails' "Magic" makes extensive use of method_missing
and const_missing
.
When you try and call a method that is not defined, ruby fires a call to method_missing
.
This is used by libraries like ActiveRecord
to implement dynamic finders.
method_missing example:
SomeModel.find_by_some_field("some_value")
is not defined.
This calls SomeModel.method_missing(:find_by_some_field, "some_value")
.
ActiveRecord then translates this call to `SomeModel.where(:some_field => "some_value")
(for performance purposes, ActiveRecord then dynamically defines this method, so next time find_by_some_field
is defined)
const_missing example:
SomeModel
has not yet been required.
The Ruby interpreter calls const_missing
with the param "SomeModel
"
Rails follows the convention "SomeModel"
should be defined in a file called some_model.rb
so const_missing
just tries require "some_model"
.
Just started learning rails. What to do now?
Python and Ruby are pretty close.
You should simply have a look at http://railsforzombies.org to get some Rails knowledge.
class methods syntax in ruby
Look at this:
person.instance_of?(Person) #=> true
Person.instance_of?(Class) #=> true
You have defined an instance method add_accessor
for all the instances of the class Class
, so Person
class can use that method because it is an instance of Class
.
I recommend yout to take a look at metaprogramming and Ruby Object Model.
Hoep this helps
Related Topics
Checking If a Variable Is Not Nil and Not Zero in Ruby
Tutorials or Screencasts on Building a Rest Web Service on Rails
Ruby: Most Concise Way to Use an Env Variable If It Exists, Otherwise Use Default Value
Ruby: How to Concatenate Array of Arrays into One
Setting Up the Logger in Rails 3
Rubygems + Cygwin: Posix Path Not Found by Ruby.Exe
Find Most Common String in an Array
Purpose of & (Ampersand) in Ruby for Procs and Calling Methods
Why Does This Nokogiri Xpath Have a Null Return
Rails: Convert Utc Datetime to Another Time Zone
When We Import CSV Data, How Eliminate "Invalid Byte Sequence in Utf-8"
Attr_Accessor on Class Variables
Rails 4 Error R14 on Heroku (Memory Quota Exceeded)
Phusion Passenger Error: You Have Activated Rack 1.2.1, But Your Gemfile Requires Rack 1.2.2