0
Posted on
Tuesday, August 29, 2017
by
醉·醉·鱼
and labeled under
ruby
- def...end, class...end, module...end都是作用域门,进入他们就会出现新的scope
- block是特殊的scope,block中initialize的局部变量在外部没法访问
- 扁平作用域可以用,define_method, Class.new, Module.new来实现。
0
Posted on
Friday, August 25, 2017
by
醉·醉·鱼
and labeled under
ruby
钩子们,来吧https://www.sitepoint.com/rubys-important-hook-methods/
# included
module Person
def name
puts "My name is Person"
end
module ClassMethods
def class_method_1
puts "Class method is called"
end
end
module InstanceMethods
def instance_method_1
puts "instance method is called"
end
end
def self.included(receiver)
receiver.extend ClassMethods
receiver.send :include, InstanceMethods
puts "#{receiver} included #{self}"
end
end
class User
include Person
end
user = User.new
user.name
user.instance_method_1
user.class.class_method_1
p User.ancestors
puts "="*16
# extended
module Animal
def name
puts "I'm an animal"
end
def self.extended(receiver)
puts "#{receiver} extended #{self}"
end
end
class Dog
extend Animal
end
Dog.name
puts "="*16
# prepended
module Ship
def name
puts "I'm a ship"
end
module ClassMethods
def class_method_1
puts "Class method is called"
end
end
module InstanceMethods
def instance_method_1
puts "instance method is called"
end
end
def self.prepended(receiver)
receiver.extend ClassMethods
receiver.send :prepend, InstanceMethods
puts "#{receiver} prepended #{self}"
end
end
class Boat
prepend Ship
def name
puts "I'm a boat. I should be overried by Ship so you won't see me."
end
end
Boat.new.name
Boat.new.instance_method_1
p Boat.ancestors
Boat.class_method_1
puts "="*16
# inherited
class Parent
def self.inherited(child_class)
puts "#{child_class} inherits #{self}"
end
def name
"My name is Parent"
end
end
class Child < Parent
end
puts Child.new.name # => My name is Parent
p Child.ancestors
puts "="*16
# method_missing
class Coffee
def price
2
end
def name
"I'm a coffee"
end
end
class Milk
def initialize(coffee)
@coffee = coffee
end
def price
super + 0.2
end
def method_missing(meth, *args)
"#{meth} not defined on #{self}"
if @coffee.respond_to?(meth)
@coffee.send(meth, *args)
else
super
end
end
end
coffee = Coffee.new
coffee_with_milk = Milk.new(coffee)
p coffee_with_milk.price
p coffee_with_milk.name
p coffee_with_milk.class.instance_methods(false) #you won't see #name method
0
Posted on
Friday, August 25, 2017
by
醉·醉·鱼
and labeled under
ruby
Ruby中的继承不仅仅可以继承实例方法,还可以继承类方法。但是,对于MIXIN的类方法,只能够用BASE.EXTEND来实现了。
class Person
def self.method_1
puts "I'm Person class method 1"
end
class << self
def method_2
puts "I'm Person class method 2"
end
end
def method_3
puts "I'm instance method 3"
end
protected
def protected_method_1
puts "I'm protected_method_1"
end
private
def private_method_1
puts "I'm private_method_1"
end
end
class Phoenix < Person
def method_4
puts "I'm instance method 4"
end
def call_protected_method_1
puts "going to call protected_method_1 from Phoenix"
protected_method_1
end
def call_private_method_1
puts "going to call private_method_1 from Phoenix"
private_method_1
end
end
Phoenix.method_1 #ok to inherit class methods
Phoenix.method_2 #ok to inherit class methods
phoenix = Phoenix.new
phoenix.method_3 #ok to inherit instance methods
phoenix.method_4 #ok
phoenix.call_protected_method_1 #ok to call protected method in parent class
# phoenix.protected_method_1 # failed. you could not call it directly
phoenix.call_private_method_1 #ok to call private method in parent class
# phoenix.private_method_1 #failed
# However, mixin class methods could not be inherited unless call base.extend
0
相对于继承,修饰的好处是不需要像继承一样创建很多方法,直接就可以转到原始对象上去。
Posted on
Friday, August 25, 2017
by
醉·醉·鱼
and labeled under
ruby
修饰,是设计模式里面提到的,不影响原始的对象,给对象附上多个组件,让其能够支持多个方法。https://robots.thoughtbot.com/evaluating-alternative-decorator-implementations-in提到了几种方法,对比了一下,觉得SimpleDelegator还不错。对于简单的case,还可以直接用Forwardable。相对于继承,修饰的好处是不需要像继承一样创建很多方法,直接就可以转到原始对象上去。
require 'delegate'
class Coffee
def cost
2
end
def origin
"Colombia"
end
end
module DecoratorClass
def class
__getobj__.class
end
end
class Milk < SimpleDelegator
include DecoratorClass
def cost
super + 0.4
end
end
class Sugar < SimpleDelegator
include DecoratorClass
def cost
super + 0.2
end
end
p Milk.ancestors
coffee = Coffee.new
p Sugar.new(Milk.new(coffee)).cost # 2.6
p Sugar.new(Sugar.new(coffee)).cost # 2.4
p Milk.new(coffee).origin # Colombia
p Sugar.new(Milk.new(coffee)).class # Coffee
0
http://www.poboke.com/study/python-solve-alphametics.html
简单换成Ruby,还可以工作。
其实内容和Python一样的,只是换成ruby而已。刚好Ruby里面也有permutation这样的方法,直接就可以用了。但是性能不是很好,虽然代码行数比较少。
题外话:说Python比Ruby简洁的,你们试试把Ruby的end抹掉以后再对比行数吧。
Posted on
Thursday, August 24, 2017
by
醉·醉·鱼
and labeled under
ruby
最近在http://exercism.io/上面刷题玩,遇到字母算术题。这个应该是目前最难的一道题了。实在不知道如何解,于是在网上搜了一下。找到一个算法,其实就是穷举法。http://www.poboke.com/study/python-solve-alphametics.html
简单换成Ruby,还可以工作。
其实内容和Python一样的,只是换成ruby而已。刚好Ruby里面也有permutation这样的方法,直接就可以用了。但是性能不是很好,虽然代码行数比较少。
题外话:说Python比Ruby简洁的,你们试试把Ruby的end抹掉以后再对比行数吧。
module Alphametics
def self.solve(input)
words = input.scan(/\w+/)
uniq_characters = words.join.chars.uniq
answer_list = []
(0..9).to_a.permutation(uniq_characters.size).each do |e|
next if words.any? { |word| word.tr(uniq_characters.join, e.join(''))[0] == '0' }
if instance_eval(input.tr(uniq_characters.join, e.join('')))
answer_list = e
break
end
end
return {} if answer_list.empty?
Hash[Hash[uniq_characters.zip answer_list].sort]
end
end
1
https://www.toptal.com/ruby/ruby-concurrency-and-parallelism-a-practical-primer
https://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/
http://blog.ifyouseewendy.com/blog/2016/02/16/ruby-concurrency-in-theory/#concurrency-vs-paralelism
并发 V.S. 并行
concurrency v.s. parallelism
如果理解没有偏差,并行就像是4个进程各自利用一个CPU执行任务。有的进程快些,有的进程慢些,但都无所谓,至少是可以一块执行的。
并发,只是说要同时处理很多事情,无关乎并行与否。如果在单核上面,启动多个线程,CPU的调度会频繁在线程之间切换,看上去是并行,实际上不是的。
在Ruby 1.9之后,可以支持多个native thread。可是,由于GIL的存在,同一时刻只允许一个线程在执行,多线程没法充分利用多核。但是,Ruby是可以利用多核的,那就是你启动多个进程,那么就可以利用多核了。
Posted on
Wednesday, August 23, 2017
by
醉·醉·鱼
and labeled under
ruby
https://www.toptal.com/ruby/ruby-concurrency-and-parallelism-a-practical-primer
https://www.igvita.com/2008/11/13/concurrency-is-a-myth-in-ruby/
http://blog.ifyouseewendy.com/blog/2016/02/16/ruby-concurrency-in-theory/#concurrency-vs-paralelism
并发 V.S. 并行
concurrency v.s. parallelism
如果理解没有偏差,并行就像是4个进程各自利用一个CPU执行任务。有的进程快些,有的进程慢些,但都无所谓,至少是可以一块执行的。
并发,只是说要同时处理很多事情,无关乎并行与否。如果在单核上面,启动多个线程,CPU的调度会频繁在线程之间切换,看上去是并行,实际上不是的。
在Ruby 1.9之后,可以支持多个native thread。可是,由于GIL的存在,同一时刻只允许一个线程在执行,多线程没法充分利用多核。但是,Ruby是可以利用多核的,那就是你启动多个进程,那么就可以利用多核了。