dodoliu的折腾笔记

生命不息,折腾不止!

0%

我在抓取一个中文网页时遇到该问题.
出现该问题的原因是字符编码不一致导致的.查看获取到的网页内容编码是 ASCII-8BIT的,所以需要强制转换为UTF-8.

1
2
3
4
code_html = HTTP.get('http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html').to_s
puts code_html.encoding.name
tmp_result = code_html.force_encoding("UTF-8").scan(/\d{6}    [\u4e00-\u9fa5]+/)
puts tmp_result

你应该遇到过通过区县查省份,通过区县查邮编的时候.一般我们会打开浏览器google一下.但是,我不想,我想敲一行代码就能迅速的查到,谁让咱是程序员呢😊.这就是我这篇记录的产生原因.
源码地址
本文将记录采用行为驱动开发(BDD)的方式,创建一个gem到发布的真实过程.
安装bundler

1
gem install bundler

创建gem项目(项目名称为 china_district_code)

1
bundler gem china_district_code

生成的目录结构应该是这样

1
2
3
4
5
6
7
8
china_district_code
- bin
- lib
.gitignore
china_district_code.gemspec
Gemfile
Rakefile
README.md

引入测试gem.打开gemfile文件,输入以下内容后运行命令: bundle install

1
2
3
4
5
source 'https://gems.ruby-china.org'

gem 'rspec'
gem 'rspec-core'
gem 'guard-rspec' #自动化测试插件

生成配置文件

1
rspec --init #初始化rspec

执行完成后,目录结构应该像这样子

1
2
3
4
5
6
7
8
9
10
11
china_district_code
- bin
- lib
- spec
- - spec_helper.rb
.gitignore
.rspec
china_district_code.gemspec
Gemfile
Rakefile
README.md

然后生成我们的测试文件

1
touch spec/china_district_code_spec.rb

生成自动化测试配置文件,下面的命令执行完成后,文件夹内会多出一个Guardfile文件(自动化测试Guard的配置文件,默认不用修改).

1
guard init rspec

然后可以启动我们的自动化测试,监控文件变化.

1
bundle exec guard

关于自动化测试插件 guard的用法可以参考
Guard的Github地址
命令说明地址
以上的基础工作完成,下面开始写我们的行为测试.
打开china_district_code_spec.rb,输入以下内容(请无视我的中国味英语o(╯□╰)o)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require 'spec_helper'

describe "China district code" do
context "district" do
it "get province,city,area info"
it "find citys by province"
it "find areas by city"
it "find province by city"
it "find city,province by area"
it "find area by district code"
end

context "post code" do
it "find post code by district code"
end
end

保存后,你会发现Guard已经自动运行了测试,并给出提示,所有的测试都是pending状态.
shell中应该像这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
00:13:39 - INFO - Running: spec/china_district_code_spec.rb
*******

Pending: (Failures listed here are expected and do not affect your suite's status)

1) China district code district get province,city,area info
# Not yet implemented
# ./spec/china_district_code_spec.rb:5

2) China district code district find citys by province
# Not yet implemented
# ./spec/china_district_code_spec.rb:6

3) China district code district find areas by city
# Not yet implemented
# ./spec/china_district_code_spec.rb:7

4) China district code district find province by city
# Not yet implemented
# ./spec/china_district_code_spec.rb:8

5) China district code district find city,province by area
# Not yet implemented
# ./spec/china_district_code_spec.rb:9

6) China district code district find area by district code
# Not yet implemented
# ./spec/china_district_code_spec.rb:10

7) China district code post code find post code by district code
# Not yet implemented
# ./spec/china_district_code_spec.rb:14


Finished in 0.00123 seconds (files took 0.14289 seconds to load)
7 examples, 0 failures, 7 pending

然后,我们来实现我们的行为,忽略折腾的过程….直接上完成的code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
china_district_code_spec.rb

require 'spec_helper'
require 'china_district_code'
require 'csv'

describe "China district code" do
context "district" do
it "get province,city,area info" do
ChinaDistrictCode::load_china_district_code
csv_folder_path = File.join(File.expand_path('../..',__FILE__),'lib','china_district_code','csv')
provinces = CSV.read(File.join(csv_folder_path,'province.csv'))
expect(provinces[0][0]).to eq('11')
end
it "find citys by province" do
expect(ChinaDistrictCode::find_citys_by_province('河北省')).to include(["130100", "石家庄市"])
end
it "find areas by city" do
expect(ChinaDistrictCode::find_areas_by_city('石家庄市')).to include(["130103", "桥东区"])
end
it "find province by city" do
expect(ChinaDistrictCode::find_province_by_city('太原')).to eql(["140000", "山西省"])
end
it "find city,province by area" do
expect(ChinaDistrictCode::find_province_city_by_area('桥东区')).to eql([["130000", "河北省"], ["130100", "石家庄市"]])
end
# it "find area by district code"
end

context "post code" do
it "find post code by district code"
end
end

然后,一个个实现我们的需求,享受由红变绿的过程(囧)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#encoding: utf-8
require 'logger'

require "china_district_code/version"
require 'china_district_code/china_district_code/loader'

LOGGER = Logger.new(File.join(File.dirname(__FILE__),'/china_district_code/log/debug.log'))

module ChinaDistrictCode

load_file 'models'
load_file 'helpers'

include CsvHelper
include DistrictHelper

#reload china district code from 'http://www.stats.gov.cn/tjsj/tjbz/xzqhdm/201401/t20140116_501070.html'
def self.load_china_district_code
DistrictHelper::get_china_district_code
end

#find citys by province  
def self.find_citys_by_province(name)
result = DistrictHelper::find_citys_by_province(name)
puts result.to_s
result
end

#find areas by city
def self.find_areas_by_city(name)
result = DistrictHelper::find_areas_by_city(name)
puts result.to_s
result
end

#find province by city
def self.find_province_by_city(name)
result = DistrictHelper::find_province_by_city(name)
puts result.to_s
result
end

#find province,city by area
def self.find_province_city_by_area(name)
result = DistrictHelper::find_province_city_by_area(name)
puts result.to_s
result
end
end

完成了gem的开发,接下来需要编译并发布.我们先修改一下gem的配置项.
打开 ‘china_district_code.gemspec’,修改如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'china_district_code/version'

Gem::Specification.new do |spec|
spec.name = "china_district_code"
spec.version = ChinaDistrictCode::VERSION
spec.authors = ["dodoliu"]
spec.email = ["donliu29@gmail.com"]

spec.summary = %q{ China District Code Query plugin }
spec.description = %q{ China District Code Query plugin }
spec.homepage = "https://github.com/dodoliu/china_district_code"

spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
spec.bindir = "exe"
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

spec.add_development_dependency "bundler", "~> 1.12"
spec.add_development_dependency "rake", "~> 10.0"
end

在发布之前,我们先安装到本地试用一下,(可以用 rake -T 查看rake任务)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
修改版本号为 VERSION = "0.0.1"
rake build #编译gem
rake install #安装到本地

-> ⮀ china_district_code ⮀ ⭠ master± ⮀ rake build
china_district_code 0.0.1 built to pkg/china_district_code-0.0.1.gem.
-> ⮀ china_district_code ⮀ ⭠ master± ⮀ rake install
china_district_code 0.0.1 built to pkg/china_district_code-0.0.1.gem.
china_district_code (0.0.1) installed.
#然后irb调用一下
2.3.1 :003 > require 'china_district_code'
=> true
2.3.1 :004 > ChinaDistrictCode.find_citys_by_province '湖南'
[["430100", "长沙市"], ["430200", "株洲市"], ["430300", "湘潭市"], ["430400", "衡阳市"], ["430500", "邵阳市"], ["430600", "岳阳市"], ["430700", "常德市"], ["430800", "张家界市"], ["430900", "益阳市"], ["431000", "郴州市"], ["431100", "永州市"], ["431200", "怀化市"], ["431300", "娄底市"], ["433100", "湘西土家族苗族自治州"]]
=> [["430100", "长沙市"], ["430200", "株洲市"], ["430300", "湘潭市"], ["430400", "衡阳市"], ["430500", "邵阳市"], ["430600", "岳阳市"], ["430700", "常德市"], ["430800", "张家界市"], ["430900", "益阳市"], ["431000", "郴州市"], ["431100", "永州市"], ["431200", "怀化市"], ["431300", "娄底市"], ["433100", "湘西土家族苗族自治州"]]
2.3.1 :005 >

完成以上步骤后,可以确认我们的gem是没有问题的.下面打包发布到https://rubygems.org/

1
rake release

你有可能会遇到这样的错误提示!(可以通过将代码提交到本地git仓库解决.(git add . && git commit -m ‘first commit’))

1
2
3
4
5
6
7
8
 -> ⮀ china_district_code ⮀ ⭠ master± ⮀ rake release
china_district_code 0.0.1 built to pkg/china_district_code-0.0.1.gem.
rake aborted!
There are files that need to be committed first.
/Users/dodoliu/.rvm/gems/ruby-2.3.1/gems/bundler-1.12.5/lib/bundler/gem_helper.rb:131:in `guard_clean'
/Users/dodoliu/.rvm/gems/ruby-2.3.1/gems/bundler-1.12.5/lib/bundler/gem_helper.rb:60:in `block in install'
Tasks: TOP => release => release:guard_clean
(See full trace by running task with --trace)

然后再次运行 rake release时,可能还会遇到下面这个错误(这是要求你的代码需要提交到远程仓库.我选择提交到github)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 ✘ ⮀ -> ⮀ china_district_code ⮀ ⭠ master± ⮀ rake release
china_district_code 0.0.1 built to pkg/china_district_code-0.0.1.gem.
Tagged v0.0.1.
Untagging v0.0.1 due to error.
rake aborted!
Couldn't git push. `git push ' failed with the following output:

fatal: No configured push destination.
Either specify the URL from the command-line or configure a remote repository using

git remote add <name> <url>

and then push using the remote name

git push <name>


/Users/dodoliu/.rvm/gems/ruby-2.3.1/gems/bundler-1.12.5/lib/bundler/gem_helper.rb:121:in `perform_git_push'
/Users/dodoliu/.rvm/gems/ruby-2.3.1/gems/bundler-1.12.5/lib/bundler/gem_helper.rb:113:in `git_push'
/Users/dodoliu/.rvm/gems/ruby-2.3.1/gems/bundler-1.12.5/lib/bundler/gem_helper.rb:64:in `block (2 levels) in install'
/Users/dodoliu/.rvm/gems/ruby-2.3.1/gems/bundler-1.12.5/lib/bundler/gem_helper.rb:145:in `tag_version'
/Users/dodoliu/.rvm/gems/ruby-2.3.1/gems/bundler-1.12.5/lib/bundler/gem_helper.rb:64:in `block in install'
Tasks: TOP => release => release:source_control_push
(See full trace by running task with --trace)

提交完成后,再次执行 rake release,看到以下内容则表示成功了.啦啦啦

1
2
3
4
5
 -> ⮀ china_district_code ⮀ ⭠ master ⮀ rake release
china_district_code 0.0.1 built to pkg/china_district_code-0.0.1.gem.
Tagged v0.0.1.
Pushed git commits and tags.
Pushed china_district_code 0.0.1 to rubygems.org.

然后自己装一下,让下载次数加1…😄

插入排序的原理:
1.从第一个元素开始,该元素可以认为是已经被排序
2.取出下一个元素,在已经排序的元素序列中从后向前扫描
3.如果该元素(已排序)大于新元素,将该元素移动到下一个位置
4.重复步骤3,知道找到已排序的元素小于或等于新元素的位置
5.将新元素插入到该位置
6.重复步骤2-5

下面是实现代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
require 'pry'
#插入排序
def insert_sort(arr)
i,j = 1,0
count = arr.length
while i < count
point = arr[i]
j = i - 1
while j >= 0 && arr[j] > point
arr[j + 1] = arr[j]
p arr
j -= 1
end
arr[j + 1] = point
p arr
i += 1
end

end

# binding.pry
insert_sort [66,13,51,76,81,26,57,69,23]

排序过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[66, 66, 51, 76, 81, 26, 57, 69, 23]
[13, 66, 51, 76, 81, 26, 57, 69, 23]
[13, 66, 66, 76, 81, 26, 57, 69, 23]
[13, 51, 66, 76, 81, 26, 57, 69, 23]
[13, 51, 66, 76, 81, 26, 57, 69, 23]
[13, 51, 66, 76, 81, 26, 57, 69, 23]
[13, 51, 66, 76, 81, 81, 57, 69, 23]
[13, 51, 66, 76, 76, 81, 57, 69, 23]
[13, 51, 66, 66, 76, 81, 57, 69, 23]
[13, 51, 51, 66, 76, 81, 57, 69, 23]
[13, 26, 51, 66, 76, 81, 57, 69, 23]
[13, 26, 51, 66, 76, 81, 81, 69, 23]
[13, 26, 51, 66, 76, 76, 81, 69, 23]
[13, 26, 51, 66, 66, 76, 81, 69, 23]
[13, 26, 51, 57, 66, 76, 81, 69, 23]
[13, 26, 51, 57, 66, 76, 81, 81, 23]
[13, 26, 51, 57, 66, 76, 76, 81, 23]
[13, 26, 51, 57, 66, 69, 76, 81, 23]
[13, 26, 51, 57, 66, 69, 76, 81, 81]
[13, 26, 51, 57, 66, 69, 76, 76, 81]
[13, 26, 51, 57, 66, 69, 69, 76, 81]
[13, 26, 51, 57, 66, 66, 69, 76, 81]
[13, 26, 51, 57, 57, 66, 69, 76, 81]
[13, 26, 51, 51, 57, 66, 69, 76, 81]
[13, 26, 26, 51, 57, 66, 69, 76, 81]
[13, 23, 26, 51, 57, 66, 69, 76, 81]

C#写习惯了,当使用Sublime写Ruby时没有IDE进行debug,实在是不习惯.
怎么办?!
不能debug,创造条件也要debug!
经过一番搜索加实践,记录如下.

需要的gem

1
2
gem install pry
gem install pry-byebug #支持ruby2.0.0,如果需要支持低版本的ruby可以使用 pry-debugger这个gem

安装了上述gem后,在需要debug的代码中添加 binding.pry

1
2
3
4
require 'pry'

binding.pry
quick_sort! [66,13,51,76,81,26,57,69,23], 0, 8

当代码运行起来后就会停在binding.pry下一行代码的位置.
pry是不支持单步调试的,为啥呢?!
如果需要单步调试就需要 pry-byebug这个gem.
pry文档
pry-byebug文档

pry-byebug的一些用法

使用简化的命令

1
2
3
4
5
6
7
8
9
#在用户根目录下创建 .pryrc配置文件
vim ~/.pryrc
#输入内容
if defined?(PryByebug)
Pry.commands.alias_command 'c', 'continue'
Pry.commands.alias_command 's', 'step'
Pry.commands.alias_command 'n', 'next'
Pry.commands.alias_command 'f', 'finish'
end

如果需要通过按enter键达到执行上一次输入的命令的效果,则在配置文件中输入以下内容.

1
2
3
4
# Hit Enter to repeat last command
Pry::Commands.command /^$/, "repeat last command" do
_pry_.run_command Pry.history.to_a.last
end

断点用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
break SomeClass#run            #断点打在 SomeClass这个类下的run方法上
break Foo#bar if baz? #当baz?返回true时,断点打在 Foo类下的bar方法上
break app/models/user.rb:15 #断点打在 user.rb的第15行
break 14 #断点打在第14行

break --condition 4 x > 2 #当x>2时,命中第四个断点
break --condition 3 #删除命中第三个断点的条件

break --delete 5 #删除第5个断点
break --disable-all #禁用所有断点

break #显示出所有断点的位置
break --show 2 #显示第二个断点附近的代码

break --delete-all #删除所有断点
break --enable 2 #启用第二个断点...为毛没有一次启用所有断点的功能?!

退出pry

1
exit!

我有个需求需要Rails连接mysql和sqlserver,这就需要rails的多数据库操作支持.
rails对mysql原生支持是很好的,所以不需要改动什么.但是操作sqlserver就需要手动配置一下了.
查了一堆资料后记录如下:
需要用到的gem:
github地址

1
2
gem 'tiny_tds'
gem 'activerecord-sqlserver-adapter', '~> 4.2.0'

database.yml针对sqlserver的配置

1
2
3
4
5
6
7
8
sqlserver_db:
adapter: sqlserver
encoding: utf8
host: localhost
port: 6381
database: sqlserver_db
username: sa
password: 123456

model的设置:
具体原因参考
在models文件夹下创建一个sqlserver_base.rb的文件,代码为:

1
2
3
4
class SqlserverBase < ActiveRecord::Base
establish_connection configurations['sqlserver_db'] #切换到sqlserver
self.abstract_class = true #声明该类为抽象类
end

sqlserver表对应的model这样声明:

1
2
3
class Friend < SqlserverBase
self.table_name = 'Friend'
end

在rails中,当下拉框select 可以多选时,如果需要在后台接收到数组参数,需要进行如下设置.
1,html中 name属性需要设置为数组形式,如下

1
2
3
4
<select name="site_event[]" id="site_event" v-model='site_event_selected' multiple>
<option value="-1" selected>--选择站点事件--</option>
<option v-for='option in site_event_options' v-bind="{value: option.eventid}" >{{option.actionname}}</option>
</select>

2,后台接收时如下

1
2
3
4
def query_pv_uv_by_day
site_events = params[:site_event].flatten
puts site_events
end

报错描述:
我有一个ajax请求

1
2
3
@get_sites = (data) ->
$.getJSON window.urls.get_sites,{brandsid:data},(result) ->
console.log result

请求的action

1
2
3
4
5
6
7
def get_sites
brandsid = params[:brandsid]
@sites = Site.find_by_brandsid brandsid
respond_to do |foramt|
format.json {render json: @sites }
end
end

然后报错信息为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ArgumentError in Backend::ExportPvUvsController#get_sites
too few arguments

Rails.root: D:/work/rails_obj/topinsight_query

Application Trace | Framework Trace | Full Trace
app/controllers/backend/export_pv_uvs_controller.rb:20:in `format'
app/controllers/backend/export_pv_uvs_controller.rb:20:in `block in get_sites'
app/controllers/backend/export_pv_uvs_controller.rb:18:in `get_sites'
Request

Parameters:

{"brandsid"=>"271ee3565366688560fc60eab0f7a5c8"}
Toggle session dump
Toggle env dump
Response

Headers:

None

让我郁闷了…我查了一整天的资料都没找到解决方法.所有的问题都是说缺少 respond_to 块.但是我的有啊…
实在憋不住了,上ruby china发帖问了一下.帖子发完没几分钟就被关小黑屋了.
我就纳闷了,我累死查了一整天的问题会这么简单?!不死心的我一边问管理员为啥关小黑屋,一边继续查.
在纠结中等到了李华顺大神的回复.他直接指出是 “format”打错了…
得知原因的我真想找个坑跳进去.怎么说我也是一个老程序员了,怎么能这么粗心.
总结:写C#一直用编译器能大大降低这种低级错误,但是在编辑器上一定要多注意、多注意、多注意!
写此篇文章的目的是警醒自己.

快速排序算法的原理:
在一个长度不小于3的序列A[0..n-1]中,对于任何 0 < n < n-1,以每一个元素p = A[n]为界,都可以将序列分隔为前、后两个子序列 A1 = A[0..n]和 A2 = A[n..n-1],则称p为序列A的轴点。然后对两个子序列排序,当子序列排序完成即可得到整个序列的排序结果(又称为 分治法)。
轴点的要点为:若一个元素是轴点,则经过排序之后,它的位置不应发生变化。
但是,实际应用中,序列中可能不存在这样一个轴点。所以需要选取轴点。
一般轴点的选取都选择数组的第一项或最后一项,但是最高效的方式是随机选取轴点.
下面的代码将采用固定轴点的方式演示快速排序.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
require 'pry'
#快速排序

def division(arr, left, right)
# point = arr[Random.new.rand(arr.length - 1)]
#确定基点
point = arr[left]
while left < right
#如果右边的数大于基点,则不操作,反之交换位置
while left < right && arr[right] >= point
right -= 1
end
swap arr, left, right
#如果左边的数小于基点,则不操作,反之交换位置
while left < right && arr[left] <= point
left += 1
end
swap arr, right, left
end
#返回轴点下标
left
end

#交换位置
def swap(arr,l,h)
arr[l],arr[h] = arr[h],arr[l]
p arr
end

def quick_sort!(arr, left, right)
if left < right
p = division arr, left, right
#递归
quick_sort! arr, left, p - 1
quick_sort! arr, p + 1, right
end
end

binding.pry
quick_sort! [66,13,51,76,81,26,57,69,23], 0, 8

排序过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
[23, 13, 51, 76, 81, 26, 57, 69, 66]
[23, 13, 51, 66, 81, 26, 57, 69, 76]
[23, 13, 51, 57, 81, 26, 66, 69, 76]
[23, 13, 51, 57, 66, 26, 81, 69, 76]
[23, 13, 51, 57, 26, 66, 81, 69, 76]
[23, 13, 51, 57, 26, 66, 81, 69, 76]
[13, 23, 51, 57, 26, 66, 81, 69, 76]
[13, 23, 51, 57, 26, 66, 81, 69, 76]
[13, 23, 26, 57, 51, 66, 81, 69, 76]
[13, 23, 26, 51, 57, 66, 81, 69, 76]
[13, 23, 26, 51, 57, 66, 81, 69, 76]
[13, 23, 26, 51, 57, 66, 81, 69, 76]
[13, 23, 26, 51, 57, 66, 76, 69, 81]
[13, 23, 26, 51, 57, 66, 76, 69, 81]
[13, 23, 26, 51, 57, 66, 69, 76, 81]
[13, 23, 26, 51, 57, 66, 69, 76, 81]

冒泡排序算法的原理:
有一组数列A[0..n-1],重复遍历该数列,一次比较两个相邻的元素A[i]和A[i+1],如果A[i]<=A[i+1]则不需要交换位置,如果A[i]>A[i+1],则需要交换位置.
实现:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require 'benchmark'

def bubble_sort!(args)
for i in 0..(args.length-1)
for j in 0..(args.length-i-2)
if (args[j+1] <=> args[j]) == -1
args[j], args[j+1] = args[j+1], args[j]
# p args
end
end
end
end

Benchmark.bm(7) do |x|
x.report('冒泡排序:') { bubble_sort! [8,3,1,2,6,5,9,10,4] }
end

遍历过程

1
2
3
4
5
6
7
8
9
10
11
12
[3, 1, 8, 2, 6, 5, 9, 10, 4]
[3, 1, 2, 8, 6, 5, 9, 10, 4]
[3, 1, 2, 6, 8, 5, 9, 10, 4]
[3, 1, 2, 6, 5, 8, 9, 10, 4]
[3, 1, 2, 6, 5, 8, 9, 4, 10]
[1, 3, 2, 6, 5, 8, 9, 4, 10]
[1, 2, 3, 6, 5, 8, 9, 4, 10]
[1, 2, 3, 5, 6, 8, 9, 4, 10]
[1, 2, 3, 5, 6, 8, 4, 9, 10]
[1, 2, 3, 5, 6, 4, 8, 9, 10]
[1, 2, 3, 5, 4, 6, 8, 9, 10]
[1, 2, 3, 4, 5, 6, 8, 9, 10]

环境:
osx 10.11.5

ruby ‘2.2.0’
gem ‘rails’, ‘4.2.3’
gem ‘mysql2’, ‘~> 0.3.18’

今天在折腾rails时,遇到mysql2与rails版本匹配问题, 虽然mysql2已经指定了 ‘~> 0.3.18’ 版本。报错信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
LiudongyuematoMacBook-Air:r_admin_demo liudongyue$ rails s
/Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/mysql2-0.3.20/lib/mysql2.rb:31:in 'require': dlopen(/Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/mysql2-0.3.20/lib/mysql2/mysql2.bundle, 9): Library not loaded: /usr/local/lib/libmysqlclient.18.dylib (LoadError)
Referenced from: /Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/mysql2-0.3.20/lib/mysql2/mysql2.bundle
Reason: image not found - /Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/mysql2-0.3.20/lib/mysql2/mysql2.bundle
from /Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/mysql2-0.3.20/lib/mysql2.rb:31:in '<top (required)>'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0@global/gems/bundler-1.9.2/lib/bundler/runtime.rb:76:in 'require'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0@global/gems/bundler-1.9.2/lib/bundler/runtime.rb:76:in 'block (2 levels) in require'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0@global/gems/bundler-1.9.2/lib/bundler/runtime.rb:72:in 'each'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0@global/gems/bundler-1.9.2/lib/bundler/runtime.rb:72:in 'block in require'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0@global/gems/bundler-1.9.2/lib/bundler/runtime.rb:61:in 'each'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0@global/gems/bundler-1.9.2/lib/bundler/runtime.rb:61:in 'require'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0@global/gems/bundler-1.9.2/lib/bundler.rb:134:in 'require'
from /Users/liudongyue/LDY/Test/r_admin_demo/config/application.rb:16:in '<top (required)>'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/railties-4.2.3/lib/rails/commands/commands_tasks.rb:78:in 'require'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/railties-4.2.3/lib/rails/commands/commands_tasks.rb:78:in 'block in server'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/railties-4.2.3/lib/rails/commands/commands_tasks.rb:75:in 'tap'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/railties-4.2.3/lib/rails/commands/commands_tasks.rb:75:in 'server'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/railties-4.2.3/lib/rails/commands/commands_tasks.rb:39:in 'run_command!'
from /Users/liudongyue/.rvm/gems/ruby-2.2.0/gems/railties-4.2.3/lib/rails/commands.rb:17:in '<top (required)>'
from bin/rails:4:in 'require'
from bin/rails:4:in '<main>'

可能的解决方法:
重装mysql,重装mysql2

1
2
3
4
brew uninstall mysql
brew install mysql
gem uninstall mysql2
gem install mysql