Created
November 9, 2012 10:58
-
-
Save sivagao/4045141 to your computer and use it in GitHub Desktop.
ruby best practices, ruby worst practices, harmful class variables. hardcoding into a corner, inheritance becomes restrictive, evails of evel(), resuce blind, method_missing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require "pstore" | |
# pay attention to the psstore;s usage | |
# @@data = PStore,new("filename.store") | |
# @@data[id] = <Ruby Object> should be surrounded by @@data.transition do <> end block | |
class User | |
def self.data | |
@data ||= PStore.new("users.store") #in class method, @data means the class instance variable. | |
end | |
def self.add(id, user_data) | |
data.transaction do #data here is interpreted as self.data method, which is class method, can be used directly without self prefix | |
data[id] = user_data | |
end | |
end | |
def self.find(id) | |
data.transaction do | |
data[id] or raise "User not found" | |
end | |
end | |
def initialize(id) | |
@user_id = id | |
end | |
def attributes | |
self.class.find(@user_id) | |
end | |
def first_name | |
attributes[:first_name] | |
end | |
end | |
Prawn::Document.generate("hello.pdf") do | |
text "Hello Prawn!" | |
end | |
module Prawn | |
class Document | |
def self.generate(filename,options={},&block) | |
pdf = Prawn::Document.new(options,&block) | |
pdf.render_file(filename) | |
end | |
end | |
end | |
class MyDocument < Prawn::Document | |
def say_hello | |
text "Hello MyDocument" | |
end | |
end | |
MyDocument.generate("hello.pdf") do | |
say_hello | |
end | |
module Prawn | |
class Document | |
def self.generate(filename,options={},&block) | |
pdf = new(options,&block) #delete the determiner | |
pdf.render_file(filename) | |
end | |
end | |
end | |
class A | |
def self.foo # why not A.foo, becuase self, easy for refactor | |
# .. | |
end | |
def self.bar | |
# .. | |
end | |
end | |
# the class include this module mixin. | |
# they can get the instnance method | |
# and class methods(class macro) defined in inner ClassMethods Module | |
# without need to use the extend | |
module GeneralLogger | |
def log(msg) | |
puts Time.now.strftime("%H:%M: ") + msg | |
end | |
module ClassMethods | |
def attr_logger(name) | |
attr_reader name | |
define_method("#{name}=") do |val| | |
log "" | |
instance_variable_set("@#{name}", val) | |
end | |
end | |
end | |
def self.included(host_class) | |
host_class.extend(ClassMethods) | |
end | |
end | |
class Example | |
include GeneralLogger | |
attr_logger :value | |
end | |
ex = Example.new | |
ex.log("New example created") | |
ex.value = 123 | |
puts "Value is #{ex.value}" | |
ex.value = "cat" | |
puts "Value is #{ex.value}" | |
user1 = User.new("Gregory Brown", balance: 2500) | |
user2 = User.new("Arthur Brown", balance: 3300) | |
user3 = User.new("Steven Brown", balance: 3200) | |
f = Filter.new([user1, user2, user3]) | |
f.search("balance > 3000") #=> [user2, user3] | |
class User | |
def initialize(name, options) | |
@name = name | |
@balance = options[:balance] | |
end | |
attr_reader :name, :balance | |
end | |
class Filter | |
def initialize(enum) | |
@collection = enum | |
end | |
def search(query) | |
@collection.select { |e| e.instance_eval(query) } | |
end | |
end | |
def search(query) | |
raise "Invalid query" unless query =~ /^(\w+) ([><!]=?|==) (\d+)$/ | |
@collection.select { |e| e.instance_eval(query) } | |
end | |
def search(query) | |
data = query.match(/^(?<attr>\w+) (?<op>[><!]=?|==) (?<val>\d+)$/) | |
@collection.select do |e| | |
attr = e.public_send(data[:attr]) | |
attr.public_send(data[:op], Integer(data[:val])) | |
end | |
end | |
>> f.search("@balance = 0") | |
=begin | |
RuntimeError: Invalid query | |
from (irb):33:in `search' | |
from (irb):39 | |
from /Users/sandal/lib/ruby19_1/bin/irb:12:in `<main>' | |
=end | |
name = @user.first_name.capitalize rescue "Anonymous" | |
name = @user.first_name ? @user.first_name.capitalize : "Anonymous" | |
>> name = @user.a_fake_method.capitalize rescue "Anonymous" | |
=> "Anonymous" | |
class Prawn::Document | |
# Provides the following shortcuts: | |
# | |
# stroke_some_method(*args) #=> some_method(*args); stroke | |
# fill_some_method(*args) #=> some_method(*args); fill | |
# fill_and_stroke_some_method(*args) #=> some_method(*args); fill_and_stroke | |
# | |
def method_missing(id,*args,&block) | |
case(id.to_s) | |
when /^fill_and_stroke_(.*)/ | |
send($1,*args,&block); fill_and_stroke | |
when /^stroke_(.*)/ | |
send($1,*args,&block); stroke | |
when /^fill_(.*)/ | |
send($1,*args,&block); fill | |
end | |
end | |
end | |
def method_missing(id,*args,&block) | |
case(id.to_s) | |
when /^fill_and_stroke_(.*)/ | |
send($1,*args,&block); fill_and_stroke | |
when /^stroke_(.*)/ | |
send($1,*args,&block); stroke | |
when /^fill_(.*)/ | |
send($1,*args,&block); fill | |
else | |
super #当遇到不在此范围内(既传递给),传回给object#method_missing, 来raise一个异常 | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment