验证码确实有点不清晰,登陆需要改善下
#1 楼 @qinfanpeng 谢谢,已经修改了
@huacnlee @gihnius @color_huo 多谢各位,现在结贴。
cipher = OpenSSL::Cipher::AES.new(128, :CBC)
cipher.encrypt
cipher.key = "quck7295abvdefgh"
cipher.iv = "abcdefgh3762quck"
encrypted = cipher.update(uuid) + cipher.final
Base64.strict_encode64(encrypted)
这样改变后,就可以正确的加密了,刚开始,只是设立了 key 和 iv,但是并没有把它赋值给 cipher 比较老的链接,但具有参考意义:http://techmedia-think.hatenablog.com/entry/20110527/1306499951
extend 是 class《self 的快捷方式,相当于打开单体类,然后 include Foo 模块。跟类 include 模块含义一样 test 方法是模块 Foo 的单体方法(类方法),存在于模块的单体类中。跟类调用类方法一样,Foo.test 类 Coo 只是一个定义在 Foo 模块中的普通类,通过 Foo::Coo 来访问。定义在模块中,为了避免类名重复,此时模块充当了命名空间的角色。 三者之间没有必然的联系
测试所用版本:Ruby 1.9.3-p448;Ruby 2.0.0-p247 定义的类变量(非共享)存储在类对象的实例变量表中,当查找类变量时,就沿着类体系结构(祖先链的反向)中类对象或模块对象的实例变量表中查找。
module M1
@@via = "m1"
end
module M2
@@via = "m2"
end
class MyClass
include M1
include M2
@@via = "myclass"
end
对于类体系结构的理解:当这行该文件时,依次记录了 MyClass 所继承的类和包含的模块,即:继承于 Object,依次包含的模块为:M1、M2,这就是 MyClass 的类体系结构:Object—>M1—>M2 NOTE: RUBY1.9中Module#class_variables和RUBY2.0中Module#class_variables的参数是不同的,ruby2.0带有参数(详见API)。 为了方便描述先定义下概念:定义的类变量和共享的类变量 在类中定义而非共享的类变量称作为:定义的类变量;而从类体系结构中共享的类变量称之为:共享的类变量。
@@via = "object"
class MyClass
@@via
def my_method
p @@via
end
end
Object.class_variables(false) #=> [:@@via]
Object.class_variable_get :@@via #=> "object"
MyClass.class_variables #=> [] ruby1.9
MyClass.class_variables(false) #=> [] ruby2.0
MyClass.new.my_method #=> "object"
Object.remove_calss_variable(:@@via) #=> "object" 删除定义的类变量
MyClass.new.my_method #会报类变量没有初始化的错误
图a
@@via = "object"
class MyClass
@@via = "myclass"
def my_method
p @@via
end
end
Object.class_variables(false) #=> [:@@via]
Object.class_variable_get :@@via #=> "myclass"
MyClass.class_variables #=> [] ruby1.9
MyClass.class_variables(false) #=> [] ruby2.0
MyClass.new.my_method #=> "myclass"
Object.remove_calss_variable(:@@via) #=> "myclass" 删除定义的类变量
MyClass.new.my_method #会报类变量没有初始化的错误
图b
通过上面图 a 和图 b 代码,特别是 MyClass.class_variables 所得的结果,可以看出,类 Object 中定义了@@via,而类 MyClass 中的@@via 是共享于 Object 中@@via。因此 MyClass 中@@via 属于共享的类变量。 图 a 和图 b 中都同过 Object.remove_calss_variable 删除 Object 中定义的@@via,因此在 MyClass 的类体系结构中@@via 不存在,所以再调用 MyClass.new.my_method 时会报类变量没有初始化的错误。 图 a 和图 b 中删除@@via 的返回值是不一样的(图 a 返回值:object,图中返回值:myclass);因为图 b 中 MyClass 修改了共享的类变量@@via 的值。
class MyClass
@@via = "myclass"
def my_method
p @@via
end
end
验证一:
MyClass.class_variables #=> [:@@via] ruby1.9
MyClass.class_variables(false) #=> [:@@via] ruby2.0
Object.class_variables(false) #=> []
MyClass.new.my_method #=> "myclass"
@@via = "object"
验证二:
MyClass.class_variables #=> [:@@via] ruby1.9 此处的类变量是MyClass对象的实例变量表中的@@via
MyClass.class_variables(false) #=> [:@@via] ruby2.0
MyClass.class_variable_get :@@via #=> "object"
Object.class_variables(false) #=> [:@@via] 此处的类变量是Object对象的实例变量表中的@@via
Object.class_variable_get :@@via #=> "object"
MyClass.new.my_method #=> "object"
验证三:
Object.remove_class_variable(:@@via)
Object.class_variables(false) #=> []
MyClass.class_variables #=> [:@@via] ruby1.9 此处的类变量是MyClass对象的实例变量表中的
MyClass.class_variables(false) #=> [:@@via] ruby2.0
MyClass.class_variable_get :@@via #=> "myclass"
MyClass.new.my_method #=> "myclass"
当执行到@@via = "myclass"这步时,首先会在类体系结构依次查找实例变量表(类对象或模块对象)若在类体系结构中某个类或模块的实例变量表中找到@@via,那么 MyClass 中@@via 属于共享的实例变量,在此处表示修改已存在的@@via 的值;若类体系结构的实例变量表中找不到@@via,那么@@via = "myclass"此处表示定义@@via 并初始化,并将@@via 及值存储在 MyClass 的实例变量表中。 验证一: MyClass 类体系结构中只存在一个@@via 且定义于 MyClass 类中。 验证二: NOTE:Module#class_variable_get 方法也是在类的体系结构中查找类变量的 由于在 Object 中定义了@@via = "object",即:Object 的实例变量表中存储着@@via。此时 MyClass 中@@via 和 Object 中@@via 是两个不同的类变量,分别存储在不同的类的实例变量表中。 方法调用(MyClass.new.my_method)中@@via 的值会从类体系结构的实例变量表中依次查找,若找到则返回该值;否则会在该方法(my_method)所在的类的实例变量表中查找,若找到则返回值,如果都没有找到的话就会报类变量没有初始化的错误。 验证三: NOTE:在这个地方的验证会出现问题,多执行几次就是正确的结果。也许是 remove_class_variable 这个方法造成的;也许是 ruby 设计的问题吧。分别在 irb 和 netbeans 中执行过。 通过前面的代码,知道 Object 和 MyClass 的实例变量表中分别存储着@@via;执行 Object.remove_class_variable(:@@via) 这行代码后,Object 实例变量表中@@via 被删除了,而 MyClass 的实例变量表中@@via 还存在,因此你执行方法调用 (MyClass.new.my_method) 在类体系结构中没有查找到@@via,而在 MyClass 实例变量表中找到了@@via 的值,且返回该值。 从上面删除@@via 的值也可以看出,MyClass 和 Object 中@@via 是两个不同的类变量。 当然也可以通过 MyClass.remove_class_variable(:@@via) 来删除 MyClass 的实例变量表中@@via,来验证这两个类变量是不相同的。
module M1
@@via = "M1"
def self.mm1
remove_class_variable(:@@via)
end
def m1
p @@via
end
end
module M2
@@via = "M2"
def self.mm2
remove_class_variable(:@@via)
end
def m2
p @@via
end
end
class MyClass
include M1
include M2
@@via = "myclass" #共享的类变量,修改M1中@@via的值
def my_method
p @@via
end
end
MyClass.ancestors #=> [MyClass, M2, M1, Object, Kernel, BasicObject]
M1.class_variables(false) #=>[:@@via]
M1.class_variable_get :@@via #=> "myclass" 类变量的值被修改过,因此返回的是修改后值
M2.class_variables(false) #=>[:@@via]
M2.class_variable_get :@@via #=> "M2"
MyClass.class_variables(false) #=>[ ]
MyClass.new.m1 #=> "myclass"
MyClass.new.m2 #=> "M2"
M1.mm1 #=> "myclass" #删除了M1中@@via
M1.class_variables(false) #=>[ ]
M2.class_variables(false) #=>[:@@via]
M2.class_variable_get :@@via #=> "M2"
MyClass.class_variables(false) #=>[ ] #没有类变量
MyClass.new.my_method #=> "M2"
MyClass.new.m2 #=> "M2"
MyClass.new.m1 #会报未初始化类变量的错误
NOTE:模块的体系结构就是模块所 include 的模块。模块 M1 和 M2 中都没有 include 模块,因此它们的类体系结构只有本身。 当执行该文件时,分别会在 M1,M2 及 MyClass 的类体系结构中查找是否存在@@via,若存在则此处@@via 表示共享的类变量,否则表示在类体系结构中未查找到@@via,在此处为定义@@via 且必须初始化。 方法调用中的类变量会在该方法所属的类或模块的体系结构中查找。例如:MyClass.new.m1 调用的是模块 M1 中的方法,则 m1 方法中@@via 的值就会在 M1 的体系结构中查找。
综上所述: 通过类体系结构 (包括模块) 来依次查找所需的类变量,为了方便记忆可以记为:祖先链的反向查找。(某个类或模块的体系结构包含在祖先链中,是祖先链的一个子集)
@hanluner ,@hxtheone ,@lyfi2003 ,@mingyuan0715 ,@kenshin54 ,@dddd1919 ,@lifuzho 这是用 1.8.7 版本测试,悲催啊,俺们公司一直在用 1.8.7。不过 1.8.7 和以后的版本源码中类变量的查找顺序也是发生了变化,1.8.7 是按祖先链的方向查找,而以后的版本则是反向查找。觉着 1.8.7 以后的版本更符合所谓类体系结构。昨天忙,没有来得及修改,稍后会上传,最新的。
class WordsParser
attr_reader :words
def initialize(words)
@words = words
methods.grep(/(.*)_parser/).select do |parser_method|
res = send(parser_method)
if res
@type = parser_method.to_s.split("_parser").first
instance_variable_get("@#{@type}").call
break
end
end
other_answer if @type == nil
end
def silent_parser
@silent = lambda{"Fine. Be that way!"} #代码有严格前后要求用快对象来延迟执行代码
words.nil? || words.strip.empty? #若代码没有前后关系的话可以
end #换成instnce_eval
def shout_parser
@shout = lambda{ "Woah, chill out!"}
words.upcase == words
end
def question_parser
@question = lambda{ "Sure."}
words.end_with?("?")
end
def other_answer
"Whatever."
end
end
class Bob
def hey(words)
WordsParser.new(words)
end
end
/lib/mytest.rb:16: warning: class variable access from toplevel singleton method /lib/mytest.rb:16:in `f3': uninitialized class variable @@a in Object (NameError) from E:/lib/mytest.rb:20
刚在本地执行了下,这个信息要详细点,
class << A def f3 @@a end end 这种情况会不会是因为匿名类的原因,相当于你重新又在一个类(匿名类)中定义了一个类变量,所以需要重新初始化下