[180725]Gitlab の Merge Request から学ぶ

どうやって Ruby 力をあげられるかを考えています。

自分のやっていること以外からどうやって知識をつけていくかが大事かなと思いつつ、興味がないことを学んでも身につかないし、課題感のないコードを読んでも、これって何に使うの？ってなると思う。

というところで Gitlab の https://gitlab.com/gitlab-org/gitlab-ce の Merge Request (GitHub でいうところの Pull Request という理解であってるはず...) を追っかけてみようと思って、気になったやつをピックアップしてまとめることにしました。
(できるだけ毎日...)

# [Create class responsible for default object store settings](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20785/diffs)
`Settings` の中にある `object_store` の設定を別クラスに切り出してる。

こういうのはどこかで使えそう。

`config/initializers/1_settings.rb の一部抜粋`

```diff
- Settings.lfs['object_store'] ||= - Settingslogic.new({})
- Settings.lfs['object_store']['enabled'] = false if Settings.lfs['object_store']['enabled'].nil?
- Settings.lfs['object_store']['remote_directory'] ||= nil
- Settings.lfs['object_store']['direct_upload'] = false if Settings.lfs['object_store']['direct_upload'].nil?
- Settings.lfs['object_store']['background_upload'] = true if - Settings.lfs['object_store']['background_upload'].nil?
- Settings.lfs['object_store']['proxy_download'] = false if Settings.lfs['object_store']['proxy_download'].nil?
- # Convert upload connection settings to use string keys, to make Fog happy
- Settings.lfs['object_store']['connection']&.deep_stringify_keys!
+ Settings.lfs['object_store'] = ObjectStoreSettings.parse(Settings.lfs['object_store'])
```

`config/object_store_settings.rb `

```diff
+ # Set default values for object_store settings
+ class ObjectStoreSettings
+   def self.parse(object_store)
+     object_store ||= Settingslogic.new({})
+     object_store['enabled'] = false if object_store['enabled'].nil?
+     object_store['remote_directory'] ||= nil
+     object_store['direct_upload'] = false if object_store['direct_upload'].nil?
+     object_store['background_upload'] = true if object_store['background_upload'].nil?
+     object_store['proxy_download'] = false if object_store['proxy_download'].nil?
+ 
+     # Convert upload connection settings to use string keys, to make Fog happy
+     object_store['connection']&.deep_stringify_keys!
+     object_store
+   end
+ end
```

# [Fix slow Markdown rendering](https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/20820/diffs)
`lib/banzai/filter/sanitization_filter.rb`

```diff
      def whitelist
        strong_memoize(:whitelist) do
-           customize_whitelist(super.dup)
+           customize_whitelist(super.deep_dup)
        end
      end

```

> The problem was that although HTML::Pipeline::SanitizationFilter.WHITELIST
is a frozen hash, the :transformers array can be modified. We need
to do deep copy of this to avoid adding duplicates.

ということらしいけど、よく理解できない...

[HTML::Pipeline::SanitizationFilter.WHITELIST](https://github.com/jch/html-pipeline/blob/master/lib/html/pipeline/sanitization_filter.rb#L40) は freeze されてるっぽい。

`freeze` されてるので、 hash の中身もちゃんと `deep_dup` で別オブジェクトで作りましょうってことだと思う。

一応 `deep_dup` で中身も別オブジェクトになっていることは確認した。

```console
[1] pry(main)> WHITELIST = { remove_contents: ['script'].freeze }.freeze
=> {:remove_contents=>["script"]}
[2] pry(main)> a_dup = WHITELIST.dup
=> {:remove_contents=>["script"]}
[3] pry(main)> a_deep_dup = WHITELIST.deep_dup
=> {:remove_contents=>["script"]}

[4] pry(main)> WHITELIST.object_id
=> 70312659760060
[5] pry(main)> a_dup.object_id
=> 70312659709620
[6] pry(main)> a_deep_dup.object_id
=> 70312659687520

[7] pry(main)> WHITELIST[:remove_contents].object_id
=> 70312659760080
[8] pry(main)> a_dup[:remove_contents].object_id
=> 70312659760080
[9] pry(main)> a_deep_dup[:remove_contents].object_id
=> 70312659687480
```

今日気になったのはこの2つ！