<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0">
  <channel>
    <title>ping94 (pupi)</title>
    <link>https://ruby-china.org/ping94</link>
    <description></description>
    <language>en-us</language>
    <item>
      <title>Ruby 中的类型转换</title>
      <description>&lt;h4 id="常用类型转换方法"&gt;常用类型转换方法&lt;/h4&gt;&lt;table class="table table-bordered table-striped"&gt;
&lt;tbody&gt;&lt;tr&gt;
&lt;th&gt;方法&lt;/th&gt;
&lt;th&gt;目标类型&lt;/th&gt;
&lt;th&gt;转换形式&lt;/th&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_a&lt;/td&gt;
&lt;td&gt;Array&lt;/td&gt;
&lt;td&gt;显式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_ary&lt;/td&gt;
&lt;td&gt;Array&lt;/td&gt;
&lt;td&gt;隐式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_h&lt;/td&gt;
&lt;td&gt;Hash&lt;/td&gt;
&lt;td&gt;显式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_hash&lt;/td&gt;
&lt;td&gt;Hash&lt;/td&gt;
&lt;td&gt;隐式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_i&lt;/td&gt;
&lt;td&gt;Integer&lt;/td&gt;
&lt;td&gt;显式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_int&lt;/td&gt;
&lt;td&gt;Integer&lt;/td&gt;
&lt;td&gt;隐式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_s&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;显式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_str&lt;/td&gt;
&lt;td&gt;String&lt;/td&gt;
&lt;td&gt;隐式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_sym&lt;/td&gt;
&lt;td&gt;Symbol&lt;/td&gt;
&lt;td&gt;隐式&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;#to_proc&lt;/td&gt;
&lt;td&gt;Proc&lt;/td&gt;
&lt;td&gt;隐式&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;&lt;h4 id="隐式转换方法"&gt;隐式转换方法&lt;/h4&gt;
&lt;p&gt;一般用于 源类型和目标类型很接近的情形。&lt;/p&gt;

&lt;p&gt;有些情况 ruby 会隐式的在参数对象上调用隐式转换方法，以便得到预期的参数类型&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;ary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;2.5&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;ary&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;  &lt;span class="c1"&gt;# =&amp;gt; 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Position&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;idx&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@index&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;idx&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_int&lt;/span&gt;
        &lt;span class="vi"&gt;@index&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="n"&gt;list&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;position&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Position&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 3&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;position&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 3&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Title&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="vi"&gt;@text&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;text&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_str&lt;/span&gt;
        &lt;span class="vi"&gt;@text&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Title&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"A Computer"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"Product Feature: "&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; Product Feature: A Computer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;我们在 Title 中实现了 #to_str 方法，它会暗示 Title 对象是一个 "类字符串" 对象，上述字符串拼接时会隐式的调用 #to_str 方法&lt;/p&gt;
&lt;h4 id="显式转换方法"&gt;显式转换方法&lt;/h4&gt;
&lt;p&gt;一般用于 源类型 和目标类型很大程度上不相干或毫无关联&lt;/p&gt;

&lt;p&gt;ruby 核心类不会像调用 隐式方法 一样调用显式方法，显式方法是为开发人员准备的&lt;/p&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; "2020-04-16 00:00:00 +0800"&lt;/span&gt;

&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_i&lt;/span&gt; &lt;span class="c1"&gt;# =&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;字符串插值&lt;/strong&gt; 是特例，ruby 会自动地调用显式类型转换方法 #to_s，将任何对象转换成字符串&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Title
    def initialize(text)
        @text = text
    end

    def to_s
        @text
    end
end

title = Title.new("A Computer")
puts "Product Feature: #{title}" # =&amp;gt; Product Feature: A Computer
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>ping94</author>
      <pubDate>Thu, 16 Apr 2020 23:04:04 +0800</pubDate>
      <link>https://ruby-china.org/topics/39753</link>
      <guid>https://ruby-china.org/topics/39753</guid>
    </item>
    <item>
      <title>Rails API 性能优化</title>
      <description>&lt;p&gt;完整的例子 &lt;a href="https://github.com/pupi94/cache_demo" rel="nofollow" target="_blank" title=""&gt;=&amp;gt; 传送门&lt;/a&gt;&lt;/p&gt;</description>
      <author>ping94</author>
      <pubDate>Thu, 01 Aug 2019 16:40:40 +0800</pubDate>
      <link>https://ruby-china.org/topics/38894</link>
      <guid>https://ruby-china.org/topics/38894</guid>
    </item>
    <item>
      <title>Ruby 中的四种等价操作符</title>
      <description>&lt;blockquote&gt;
&lt;p&gt;每定义一个类时，它们都继承了四个不同的等价性检查方法，理解其工作方式才能帮助你在需要的时候更好的重载它们&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="1、equal?"&gt;1、equal?&lt;/h4&gt;
&lt;p&gt;检测是否为同一对象 (具有相同的 object_id)&lt;/p&gt;
&lt;h4 id="2、eql?"&gt;2、eql?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;比较是否为相同的类型和相等的值&lt;/li&gt;
&lt;li&gt;当为自定义的类时，其默认的行为与 equal？相同&lt;/li&gt;
&lt;li&gt;Hash 在冲突检测时使用 eql？来比较键对象&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;当使用对象为 hash 的键时，如果希望两个相似的对象具有相同的哈希键时需要同时实现 hash 和 eql？两个方法&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Color
    attr_reader :name
    def initialize(name)
        @name = name
    end

    def hash
        name.hash
    end

    def eql?(o)
        name.eql?(o.name)
    end
end
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="3、==操作符"&gt;3、&lt;code&gt;==&lt;/code&gt;操作符&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;比较两个对象的值是否相同&lt;/li&gt;
&lt;li&gt;两个数字使用时操作符会将对象做类型的隐式转换&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;irb&amp;gt; 1 == 1.0
---&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="4、 ===操作符"&gt;4、 &lt;code&gt;===&lt;/code&gt;操作符&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;=== 默认行为只是将对象传给 &lt;code&gt;==&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;某些类重新定义了 === 方法，如 Regexp(正则表达式匹配)&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;irb&amp;gt; /er/ === 'typer'
---&amp;gt; true
irb&amp;gt; 'typer' === /er/
---&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;类和模块也重新定义了 === 方法&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;irb&amp;gt; [1,2,3].is_a?(Array)
---&amp;gt; true
irb&amp;gt; Array === [1,2,3]
---&amp;gt; true
irb&amp;gt; [1,2,3] === Array
---&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;case 表达式使用 === 来测试每个 when 语句的值，左操作数是 when 的参数，右操作数是 case 的参数&lt;/li&gt;
&lt;/ul&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case command
when 'start' then start
when 'stop', 'quit' then stop
when /^cd\s+(.+)$/ then cd($1)
when Numeric then timer(command)
else rails error
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;等价于&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;case command
if 'start' === command then start
elsif 'stop' === command then stop
elsif 'quit' === command then stop
elsif /^cd\s+(.+)$/ === command then cd($1)
elsif Numeric === command then timer(command)
else rails error
end
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>ping94</author>
      <pubDate>Sat, 09 Jun 2018 12:32:46 +0800</pubDate>
      <link>https://ruby-china.org/topics/36925</link>
      <guid>https://ruby-china.org/topics/36925</guid>
    </item>
    <item>
      <title>Rails 5.2 + Puma + Capistrano3 + Nginx + Sidekiq 自动化部署</title>
      <description>&lt;p&gt;自己整了一个个人网站，然后将网站部署到了阿里云服务器上。由于使用的 rails 和 Capistrano3 这些都是最新的版本，网上的一些资料都有些过时，遇到很多问题，然后只能耐心的去看官方文档，整个部署过程整理了一下笔记以供参考&lt;/p&gt;
&lt;h3 id="一、部署环境"&gt;一、部署环境&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;centos7(阿里云服务器)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/capistrano/capistrano" rel="nofollow" target="_blank" title=""&gt;Capistrano 3.10&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Ruby2.4.4&lt;/li&gt;
&lt;li&gt;Rails 5.2&lt;/li&gt;
&lt;li&gt;Puma3.11&lt;/li&gt;
&lt;li&gt;Nginx1.13&lt;/li&gt;
&lt;li&gt;Sidekiq5.1.3(monit 5.25)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ruby、nginx、redis 和 monit 的安装过程这里略过&lt;/p&gt;
&lt;h3 id="二、初始化部署项目并配置Capistrano(以部署production环境为例)"&gt;二、初始化部署项目并配置 Capistrano(以部署 production 环境为例)&lt;/h3&gt;
&lt;p&gt;建好部署项目后在 Gemfile 中添加 Capistrano 相关 gem&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;gem "capistrano", "~&amp;gt; 3.10", require: false
gem 'capistrano-rails', '~&amp;gt; 1.3', require: false
gem 'capistrano3-puma', '~&amp;gt; 3.1', require: false
gem 'capistrano-sidekiq', '~&amp;gt; 1.0'
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="初始化 capistrano"&gt;初始化 capistrano&lt;/h5&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cap install
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;cap T&lt;/code&gt; 可用来查看可执行任务列表&lt;/p&gt;

&lt;p&gt;这里直接把代码的链接贴出来了 --&amp;gt; &lt;a href="https://github.com/puping94/myblog_deploy" rel="nofollow" target="_blank" title=""&gt;传送门&lt;/a&gt;&lt;/p&gt;
&lt;h3 id="三、部署项目"&gt;三、部署项目&lt;/h3&gt;&lt;h4 id="1、检查需要的文件和目录"&gt;1、检查需要的文件和目录&lt;/h4&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cap production deploy:check
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;根据提示创建对应文件或文件夹&lt;/p&gt;
&lt;h5 id="新建shared/config/database.yml文件"&gt;新建 shared/config/database.yml 文件&lt;/h5&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;production:
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root
  password: xxxxxxx
  host: localhost
  database: myblog_production
&lt;/code&gt;&lt;/pre&gt;&lt;h5 id="新建master.key文件"&gt;新建 master.key 文件&lt;/h5&gt;
&lt;p&gt;将本地项目 config/master.key 中的内容复制进去。&lt;/p&gt;
&lt;h4 id="2、部署并启动puma"&gt;2、部署并启动 puma&lt;/h4&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cap production puma:config #第一次deploy之前必须将运行此命令，否则puma无法启动
$ cap production deploy
$ cap production puma:start
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;部署之后最好检查一下 puma 是否正常启动&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cap production puma:status
&lt;/code&gt;&lt;/pre&gt;&lt;h4 id="3、有新代码提交后重新部署"&gt;3、有新代码提交后重新部署&lt;/h4&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cap production deploy
$ cap production puma:restart
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="四、nginx配置"&gt;四、nginx 配置&lt;/h3&gt;
&lt;p&gt;nginx 常用命令&lt;/p&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ sbin/nginx #启动
$ sbin/nginx -t #检查配置文件
$ sbin/nginx –s reload #重启
$ sbin/nginx –s stop #停止
&lt;/code&gt;&lt;/pre&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;upstream puma_myblog_production {
  server unix:/var/www/myblog/shared/tmp/sockets/puma.sock fail_timeout=0;
}

# 当用户使用HTTP的URL访问时重定向到https的url上去
server {
  listen 80;
  server_name www.xxx.com;
  return 301 https://$server_name$request_uri;
}

server {
  listen 443 ssl;
  server_name www.xxx.com;
  root /var/www/myblog/current/public;
  try_files $uri/index.html $uri @puma_myblog_production;

  # HTTPS 配置begin
  # CA证书是在阿里云上购买的免费版的，有点不太稳定
  ssl on;
  ssl_certificate   ../cert/214690888480272.pem;
  ssl_certificate_key  ../cert/214690888480272.key;
  ssl_session_timeout 5m;
  ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
  ssl_prefer_server_ciphers on;
  # https 配置end

  client_max_body_size 4G;
  keepalive_timeout 10;

  error_page 500 502 504 /500.html;
  error_page 503 @503;

  location @puma_myblog_production {
    proxy_pass http://puma_myblog_production;

    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_redirect off;
    proxy_set_header  X-Forwarded-Proto $scheme;
    proxy_set_header  X-Forwarded-Ssl on; # Optional
    proxy_set_header  X-Forwarded-Port $server_port;
    proxy_set_header  X-Forwarded-Host $host;

    # limit_req zone=one;
    access_log /var/www/myblog/shared/log/nginx.access.log;
    error_log /var/www/myblog/shared/log/nginx.error.log;
  }

  location ^~ /assets/ {
    gzip_static on;
    expires max;
    add_header Cache-Control public;
  }

  location = /50x.html {
    root html;
  }

  location = /404.html {
    root html;
  }

  location @503 {
    error_page 405 = /system/maintenance.html;
    if (-f $document_root/system/maintenance.html) {
      rewrite ^(.*)$ /system/maintenance.html break;
    }
    rewrite ^(.*)$ /503.html break;
  }

  if ($request_method !~ ^(GET|HEAD|PUT|PATCH|POST|DELETE|OPTIONS)$ ){
    return 405;
  }

  if (-f $document_root/system/maintenance.html) {
    return 503;
  }
}
&lt;/code&gt;&lt;/pre&gt;</description>
      <author>ping94</author>
      <pubDate>Fri, 08 Jun 2018 17:41:59 +0800</pubDate>
      <link>https://ruby-china.org/topics/36924</link>
      <guid>https://ruby-china.org/topics/36924</guid>
    </item>
  </channel>
</rss>
