Forms first off, a bit of idioms created based on RESTful:
forms if you where to put in def new to render edit, when rendered it knows to post to create rather than edit,
and know is calling edit to put to update
AciveRecord can query objects via the new_record? method (@thing.new_record?), which means that it can determine whether it is a new object and so RESTfully can determine whether to create or update
David doesn't like this as it has the feeling that it is not very elegant. It is over economising. Use a partial if there is >serious overlap, and then have different templates, which can have extra bits.
(This was originally a plugin simply_helpful, now core and only works with REST)
Subclass
subdirectories
You can
script/generate controller admin/things
in routes
map.namespace :admin do |n|
n.resources :things
end
this gives a set of restful routes like new_admin_thing
with a
parallel tree of views app/views/admin/things/
Then onto some more Ruby
Procs and Callbacks
Ruby: proc (function) objects
anonymous functions which are themselves objects (and can bepassed around, etc)
Proc can remember a local variable within itself, rather than it going out of scope and being garbage collected
guest095:yadb ajb$ irb
>> Proc.new {}
=> #<Proc:0x00000000@(irb):1>
>> lambda {}
=> #<Proc:0x00000000@(irb):2>
>> proc {}
=> #<Proc:0x00000000@(irb):3>
lambda and proc are synonyms, but different from Proc.new
code blocks can be captured within a def method
p = lambda {|x| puts x * 10}
array = [1,2,3,4,5,]
array.each(&p)
def convert(n, &block) <-- special & argument syntax captures code block as a Proc object
end
puts convert (10) { |x| x * 30 }
alternative
def convert(n)
if block_given?
yield(n)
else
n * 2
end
end
good unless you need to objectify the method for some reason
it is a closure on the variables that exist around where it is created
>> y= 1; [1,2,3].each {|x| puts x * 10; puts y; y += 1 }
10
1
20
2
30
3
=> [1, 2, 3]
>> puts y
4
=> nil
but leaves alone ones created after its creation
>> class Counter
>> def self.create(n=0, inc=1)
>> return Proc.new{ n += inc; n - inc }
>> end
>> end
=> nil
>> c = Counter.create
=> #<Proc:0x0059f330@(irb):3>
>> puts c.call
0
=> nil
>> puts c.call
1
=> nil
>> n = 222
=> 222
>> c = Counter.create
=> #<Proc:0x0059f330@(irb):3>
>> puts c.call
0
=> nil
>> puts c.call
1
=> nil
>> c = Counter.create(5,5)
=> #<Proc:0x0059f330@(irb):3>
>> puts c.call
5
=> nil
>> puts c.call
10
=> nil
>> puts n
222
=> nil
you can write code blocks with {} or do - end, but they are not interchangeable
>> puts [1,2,3].map {|x| x * 10 }
10
20
30
=> nil
>> puts [1,2,3].map do |x| x * 10 end
1
2
3
=> nil
you can write a method to warn about the presence of a block (or not), but not every ruby method will do this
>> def m; raise "A block!" if block_given?; end
=> nil
>> m
=> nil
>> m {}
RuntimeError: A block!
from (irb):21:in `m'
from (irb):23
>> m do |x| x*10 end
RuntimeError: A block!
from (irb):27:in `m'
from (irb):28
>> def m; raise "A block!" if !block_given?; end
=> nil
>> m {}
=> nil
>> m
RuntimeError: A block!
from (irb):24:in `m'
from (irb):26
Built in callbacks
method_missing
Modules: - included
Classes: - inherited
>> module M
>> def talk; puts "Hi!"; end
>> end
=> nil
>> M.new
NoMethodError: undefined method `new' for M:Module
from (irb):4
you can't instantiate a module, but they are good for mixins
you can include Classes in Modules
>> module Violin
>> class String; end
>> end
=> nil
modules can give their methods to a class, via include
?> class Person
>> include M
>> end
=> Person
>> andy = Person.new
=> #<Person:0x59b71c>
>> andy.talk
Hi!
=> nil
Classes - inherited
>> class Furniture
>> def self.inherited(c)
>> puts "#{self} has been inherited by class #{c}"
>> end
>> end
=> nil
>>
?> class Chair < Furniture
>> end
Furniture has been inherited by class Chair
=> nil
extend
?> module N
>> def walk; puts "I am walking!"; end
>> end
=> nil
>> Person.ancestors
=> [Person, M, Object, Kernel]
>> andy.walk
NoMethodError: undefined method `walk' for #<Person:0x59b71c>
from (irb):29
>> andy.extend(N)
=> #<Person:0x59b71c>
>> andy.walk
I am walking!
=> nil
use extend via a module if you want to replace core methods as this is a low impact way
>> module M;def shout;puts "HI!!!!";end;end
=> nil
>> class C;end
=> nil
>> C.extend(M)
=> C
>> C.shout
HI!!!!
=> nil
Classes are objects. It extends the singleton methods on the object
equivalent to
class << C; include M; end
extend gives class methods, include are instance methods, all though David wasn't really sure what that ultimately would mean
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment