2017年7月26日 星期三

Null object pattern


在需要 check object 是否存在的時候使用 null object pattern,如果 object 不存在就用 null object,null object 提供跟原本 object 很像的 API 接口,並預設這些 API 的行為,讓程式可以安心的使用這些 API


https://www.tutorialspoint.com/design_pattern/null_object_pattern.htm

Ruby:

https://gist.github.com/davidbella/6918455

開發第一個智能合約 - 環境準備



首先安裝框架
http://truffleframework.com/docs/getting_started/client



測試環境
https://github.com/ethereumjs/testrpc



package:
https://www.ethpm.com/registry




Ruby exceptions 進階

backtrace

error.backtrace

可以看出是在哪裡報錯



如果 rescue 後再 raise 還可以看出是上一個 error 是什麼

def fail_and_reraise
  raise NoMethodError
rescue
  raise RuntimeError
end

begin
  fail_and_reraise
rescue => e
  puts "#{ e } caused by #{ e.cause }"
end”

Excerpt From: Starr Horne. “Mastering Ruby Exceptions.” iBooks.


TracePoint

可以做成 log 系統的好東西,自動 catch 每個 error 並記錄
http://ruby-doc.org/core-2.2.0/TracePoint.html


Ruby 可以在 class 內定義 exception method,這樣就可以 raise 這個 class


不囉唆,上 code

Raising Non-Exceptions

If we provide an exception method, any object can be raised as an exception.

Imagine you have a class called HTMLSafeString which contains a string of text. You might want to make it possible to pass one of these “safe” strings to raise just like a normal string. To do this we simply add an exception method that creates a new RuntimeError.

class HTMLSafeString
  def initialize(value)
    @value = value
  end
 
  def exception
    RuntimeError.new(@value)
  end
end

raise HTMLSafeString.new("helloworld")”


Excerpt From: Starr Horne. “Mastering Ruby Exceptions.” iBooks.

Form object pattern


優點:

1. 把讓 controller 和 view 的邏輯拆開,讓 form object 負責,符合 single responsibility principle
2. 如果 include active_record 可以享用 validations, errors 和符合 convention 等優點




http://culttt.com/2015/11/04/using-form-objects-in-ruby-on-rails/
https://webuild.envato.com/blog/creating-form-objects-with-activemodel-and-virtus/
https://robots.thoughtbot.com/activemodel-form-objects

2017年7月25日 星期二

[網路原理重修系列][3] Socket, Process

應用層運行的程序叫做 process,每個 process 經過 socket 和傳輸層溝通,socket 其實就是提供給應用層跟傳輸層溝通的 API
如果 IP 是地址,port 就像房間號,主流的幾個 port 已經在操作系統中預先定義了例如 80 是 web application, 25 是 smtp email 用的

2017年7月22日 星期六

在 rails 內避免數字因為 race condition 而有誤


例如我有個 Account model 內有 balance column,可以這樣做:



```ruby
  def increment_balance(amount)
    self.class.connection.execute "update accounts set balance = balance + #{amount} where id = #{id}"
    add_to_transaction # so after_commit will be triggered
    self
  end
```

這樣就算我有兩個 account instance 同時存入也沒關係,因為他增加的值是從 database 的值去加的,如果是用

```ruby
account.update(amount: new_amount)
```

這種作法的話就會變成直接 update 成新的值,就可能會有 race condition 的問題