Showing posts with label Ruby on Rails. Show all posts
Showing posts with label Ruby on Rails. Show all posts

Sunday, March 16, 2014

Learning Notes about Metaprogramming Ruby

1. Metaprogramming is writing code that manipulates language constructs at runtime.

2. Named Arguments allows you to set arguments by names rather than by position.

3. Argument array, the * operator collects multiple arguments in a single array.

def my_method(*args)
   args
end

my_method(1, '2', 'three') # => [1, "2", "three"]

4. Self Yield
When you pass a block to a method, you expect the method to call back to the block through yield.

5. Metaprogramming: design a Domain Specific Language (DSL) and then using that DSL to write your own program.

6. An object's instance variables live in the object itself, and an object's methods live in the object's class. (Objects of the same class share methods but don't share instance variables)

7. A class is just a souped-up module with 3 additional methods---new(), allocate() and supreclass()---that allows you to create objects or arrange classes into hierarchies.

8. Classes are nothing but objects, class names are nothing but constants.

9. Module is to be imported somewhere (or used as a Namespace) and class is to be instantiated or inherited.

10. load() to execute code and require() to import libraries.

11. When you call a method, actually you are sending a message to an object.

12. Symbol is immutable and some operations (such as comparison) run faster on symbol rather than on string. Symbol is used as the name of things, particularly, name of metaprogramming related things such as methods.

13. Black slate, a class that has fewer methods than the Object class itself since removing most inherited methods from your proxies right away.

14. Procs vs. Lambdas
1) In a lambda, return just returns from the lambda.
2) In the way check their arguments, lambda tends to be less tolerant than procs (and regular blocks).

15. Blocks(they aren't really "objects", but they are still callable): Evaluated in the scope in which they're defined.

Procs: Objects of class Proc. Like blocks, they are evaluated in the scope where they're defined.

Lambdas: Also objects of class Proc but subtly different from regular procs. They're closures like blocks and procs, and as such they're evaluated in the scope where they're defined.

Methods: Bound to an object, they are evaluated in that object's scope. They can also be unbound from their scope and rebound to the scope of another object.

16. Around Alias in three steps:
1) You alias a method.
2) You redefine it.
3) You call the old method from the new method.

17. When you learn that, when it comes right down to it, code is just text.

18. A master developer sits on top of mountain, meditating.
You are smart enough to learn, but are you smart enough to forget what you have learned? There's no such thing as metaprogramming. It's just programming all the way through.

19. Trade-off of metaprogramming
Complexity for beginner vs Complexity for experts

Internal Complexity vs External Complexity (By making insides of your code more complex, you make your library simpler for clients.

Complexity by Terseness vs Complexity by Duplication

Complexity for humans vs Complexity for tools

20. Class Extension Mixing turns methods in module into class methods, modules make code easier to understand and change.

21. Metaprogramming code can get complex but you can manage the complexity with unit testing which help you write code clean and error-free.

22. Ruby with Metaprogramming expects you manipulate the language constructs, tweak the object model, reopen classes, define methods dynamically, and manage scopes with blocks. (There's no such thing as metaprogramming. It's just programming all the way through.)

Monday, February 17, 2014

Learning Notes about Agile Web Development with Rails (3)

Basic Ruby programming language knowledge

1. Ruby Names

Local variables, method parameters, and method names should all start with
a lowercase letter or with an underscore: order, line_item, and xr2000 are all
valid. Instance variables begin with an “at” sign (@), such as @quantity and @product_id. The Ruby convention is to use underscores to separate words in a multiword method or variable name (so
line_item is preferable to lineItem).

Class names, module names, and constants must start with an uppercase
letter. By convention they use capitalization, rather than underscores, to dis-
tinguish the start of words within the name. Class names look like Object,
PurchaseOrder, and LineItem.

Rails uses symbols to identify things. In particular, it uses them as keys when
naming method parameters and looking things up in hashes.

2. Methods

You don’t need a semicolon at the end of a statement as long as you put each
statement on a separate line. Ruby comments start with a # character and
run to the end of the line. Indentation is not significant (but two-character
indentation is the de facto Ruby standard).

Ruby doesn’t use braces to delimit the bodies of compound statements and
definitions (such as methods and classes). Instead, you simply finish the body
with the keyword end. The keyword return is optional, and if not present, the
results of the last expression evaluated will be returned.

3. Strings

This previous example also showed some Ruby string objects. One way to cre-
ate a string object is to use string literals, which are sequences of characters
between single or double quotation marks. The difference between the two
forms is the amount of processing Ruby does on the string while constructing
the literal. In the single-quoted case, Ruby does very little. With a few excep-
tions, what you type into the single-quoted string literal becomes the string’s
value.

In the double-quoted case, Ruby does more work. First, it looks for substitu-
tions—sequences that start with a backslash character—and replaces them
with some binary value. The most common of these is \n, which is replaced
with a newline character. When you write a string containing a newline to the
console, the \n forces a line break.

Second, Ruby performs expression interpolation in double-quoted strings. In
the string, the sequence #{expression } is replaced by the value of expression.

4. Arrays and Hashes

Ruby’s arrays and hashes are indexed collections. Both store collections of
objects, accessible using a key. With arrays, the key is an integer, whereas
hashes support any object as a key. Both arrays and hashes grow as needed
to hold new elements. It’s more efficient to access array elements, but hashes
provide more flexibility. Any particular array or hash can hold objects of dif-
fering types; you can have an array containing an integer, a string, and a
floating-point number, for example.

You can create and initialize a new array object using an array literal—a set
of elements between square brackets. Given an array object, you can access
individual elements by supplying an index between square brackets, as the
next example shows. Ruby array indices start at zero.

In Rails, hashes typically use symbols as keys. Many Rails hashes have been
subtly modified so that you can use either a string or a symbol interchangeably
as a key when inserting and looking up values.

nil is an object, just like any other, that happens to represent
nothing. nil means false when used in conditional expressions.

5. Regular Expressions

A regular expression lets you specify a pattern of characters to be matched in
a string. In Ruby, you typically create a regular expression by writing /pattern/
or %r{pattern}.

6. Block

Code blocks are just chunks of code between braces or between do...end. A
common convention is that people use braces for single-line blocks and do/end
for multiline blocks.

A method can invoke an associated block one or more times using the Ruby
yield statement. You can think of yield as being something like a method call
that calls out to the block associated with the method containing the yield. 
You can pass values to the block by giving parameters to yield. 

7. Exceptions

Exceptions are objects (of class Exception or its subclasses). The raise method
causes an exception to be raised. This interrupts the normal flow through the
code. Instead, Ruby searches back through the call stack for code that says it
can handle this exception.

Both methods and blocks of code wrapped between begin and end keywords
intercept certain classes of exceptions using rescue clauses.

rescue clauses can be directly placed on the outermost level of a method defi-
nition without needing to enclose the contents in a begin/end block.

8. Modules

Modules are similar to classes in that they hold a collection of methods, con-
stants, and other module and class definitions. Unlike classes, you cannot
create objects based on modules.

Modules serve two purposes.
First, they act as a namespace, letting you define methods whose names will not
clash with those defined elsewhere.
Second, they allow you to share functionality between classes—if a class mixes in a
module, that module’s instance methods become available as if they had been
defined in the class. Multiple classes can mix in the same module, sharing the
module’s functionality without using inheritance. You can also mix multiple
modules into a single class.

Helper methods are an example of where Rails uses modules. Rails automat-
ically mixes these helper modules into the appropriate view templates.

9. YAML

YAML is a recursive acronym which stands for YAML Ain’t Markup Language.
In the context of Rails, YAML is used as a convenient way to define config-
uration of things such as databases, test data, and translations.

10. Marshaling Objects

Ruby can take an object and convert it into a stream of bytes that can be stored
outside the application. This process is called marshaling. This saved object
can later be read by another instance of the application (or by a totally separate
application), and a copy of the originally saved object can be reconstituted.

There are two potential issues when you use marshaling. First, some objects
cannot be dumped. If the objects to be dumped include bindings, procedure or
method objects, instances of class IO, singleton objects, or if you try to dump
anonymous classes or modules, a TypeError will be raised.
Second, when you load a marshaled object, Ruby needs to know the definition
of the class of that object (and of all the objects it contains).

Rails uses marshaling to store session data. If you rely on Rails to dynam-
ically load classes, it is possible that a particular class may not have been
defined at the point it reconstitutes session data. For that reason, you’ll use
the model declaration in your controller to list all models that are marshaled.
This preemptively loads the necessary classes to make marshaling work.

11. Ruby Idioms

1) lambda

The lambda operator converts a block into a object of type Proc. 

2) require File.dirname(__FILE__) + ’/../test_helper’

Ruby’s require method loads an external source file into our application.
This is used to include library code and classes that our application relies
on. In normal use, Ruby finds these files by searching in a list of direc-
tories, the LOAD_PATH.


Learning Notes about Agile Web Development with Rails (2)

Chapter 3

1. MVC architecture

The model is responsible for maintaining the state of the application. Some-
times this state is transient, lasting for just a couple of interactions with the
user. Sometimes the state is permanent and will be stored outside the appli-
cation, often in a database.

model is more than just data; it enforces all the business rules that apply
to that data. (The model acts as both a gatekeeper and a data store.)

The view is responsible for generating a user interface, normally based on
data in the model. Although the view may present the user with various ways of
inputting data, the view itself never handles incoming data. The view’s work
is done once the data is displayed. 

Controllers orchestrate the application. Controllers receive events from the
outside world (normally user input), interact with the model, and display an
appropriate view to the user.

The MVC architecture was originally intended for conventional GUI applica-
tions, where developers found the separation of concerns led to far less cou-
pling, which in turn made the code easier to write and maintain. 

2. Rails processing flow

1) In a Rails application, an incoming request is first sent to a router, which
works out where in the application the request should be sent and how the
request itself should be parsed. 

2) The routing component receives the incoming request and immediately picks it
apart. 
 
3) Controller interacts with model

4) Controller invokes view

5) View renders next browser screen

3. Why need a framework such as Ruby on Rails?
 The answer is straightforward: Rails handles all of the low-level housekeeping for
you—all those messy details that take so long to handle by yourself—and lets
you concentrate on your application’s core functionality.

4. Object-Relational Mapping
Relational databases are actually designed around mathematical
set theory. Although this is good from a conceptual point of view, it makes it
difficult to combine relational databases with object-oriented (OO) program-
ming languages. Objects are all about data and operations, and databases are
all about sets of values. Operations that are easy to express in relational terms
are sometimes difficult to code in an OO system. The reverse is also true.
 
So, an ORM layer maps tables to classes, rows to objects, and columns to
attributes of those objects. Class methods are used to perform table-level oper-
ations, and instance methods perform operations on the individual rows.

Active Record
Active Record is the ORM layer supplied with Rails. It closely follows the stan-
dard ORM model: tables map to classes, rows to objects, and columns to object
attributes. It differs from most other ORM libraries in the way it is configured.
By relying on convention and starting with sensible defaults, Active Record
minimizes the amount of configuration that developers perform. 

Active Record relieves us of the hassles of dealing with the underlying
database, leaving us free to work on business logic.
But Active Record does more than that. Active Record integrates seam-
lessly with the rest of the Rails framework. If a web form sends the application
data related to a business object, Active Record can extract it into our model.
Active Record supports sophisticated validation of model data, and if the form
data fails validations, the Rails views can extract and format errors.

Active Record is the solid model foundation of the Rails MVC architecture.

5. Action Pack: The View and Controller
When you think about it, the view and controller parts of MVC are pretty
intimate. The controller supplies data to the view, and the controller receives
events from the pages generated by the views. Because of these interactions,
support for views and controllers in Rails is bundled into a single component,
Action Pack.
    
6. View Support
In Rails, the view is responsible for creating either all or part of a response to
be displayed in a browser, processed by an application or sent as an email.
At its simplest, a view is a chunk of HTML code that displays some fixed text.
More typically you’ll want to include dynamic content created by the action
method in the controller.

In Rails, dynamic content is generated by templates, which come in three
flavors. 
1) The most common templating scheme, called Embedded Ruby (ERb),
embeds snippets of Ruby code within a view document, in many ways similar
to the way it is done in other web frameworks, such as PHP or JSP. 
2) XML Builder can also be used to construct XML documents using Ruby code—
the structure of the generated XML will automatically follow the structure of
the code.
3) Rails also provides RJS views. These allow you to create JavaScript fragments
on the server that are then executed on the browser. This is great for creating
dynamic Ajax interfaces.

7. Controller!
The Rails controller is the logical center of your application. It coordinates the
interaction between the user, the views, and the model. However, Rails handles
most of this interaction behind the scenes; the code you write concentrates on
application-level functionality. This makes Rails controller code remarkably
easy to develop and maintain.

The controller is also home to a number of important ancillary services:
• It is responsible for routing external requests to internal actions. It han-
dles people-friendly URLs extremely well.
• It manages caching, which can give applications orders-of-magnitude
performance boosts.
• It manages helper modules, which extend the capabilities of the view
templates without bulking up their code.
• It manages sessions, giving users the impression of ongoing interaction
with our applications.

Saturday, February 15, 2014

Learning Notes about Agile Web Development with Rails

Ruby on Rails two philosophy:
1. DRY, don't repeat yourself.
Modulize the program, remove duplication. Ruby does very well basically, Rails was written in Ruby.
2. Convention over configuration.
Follow convention, write less code than use XML in Java.

Agile development core ideas:
1. Individuals and interactions over processes and tools
2. Working software over comprehensive documentation
3. Customer collaboration over contract negotiation
4. Responding to change over following a plan

Rails is agile itself! Elegant, faster, programmer-friendly.