Project1
标题: VA多了好多":",为什么要用":" [打印本页]
作者: 九靈 时间: 2014-8-4 20:06
标题: VA多了好多":",为什么要用":" Scene_Menu
#--------------------------------------------------------------------------
# ● 生成指令窗口
#--------------------------------------------------------------------------
def create_command_window
@command_window = Window_MenuCommand.new
@command_window .set_handler ( :item , method( :command_item ) )
@command_window .set_handler ( :skill , method( :command_personal ) )
@command_window .set_handler ( :equip , method( :command_personal ) )
@command_window .set_handler ( :status , method( :command_personal ) )
@command_window .set_handler ( :formation , method( :command_formation ) )
@command_window .set_handler ( :save , method( :command_save ) )
@command_window .set_handler ( :game_end , method( :command_game_end ) )
@command_window .set_handler ( :cancel , method( :return_scene ) )
end
#--------------------------------------------------------------------------
# ● 生成指令窗口
#--------------------------------------------------------------------------
def create_command_window
@command_window = Window_MenuCommand.new
@command_window .set_handler ( :item , method( :command_item ) )
@command_window .set_handler ( :skill , method( :command_personal ) )
@command_window .set_handler ( :equip , method( :command_personal ) )
@command_window .set_handler ( :status , method( :command_personal ) )
@command_window .set_handler ( :formation , method( :command_formation ) )
@command_window .set_handler ( :save , method( :command_save ) )
@command_window .set_handler ( :game_end , method( :command_game_end ) )
@command_window .set_handler ( :cancel , method( :return_scene ) )
end
问题:
冒号有何用啊?
为什么要用?
不能用@吗?(如@command_item)
作者: 喵呜喵5 时间: 2014-8-4 20:12
本帖最后由 喵呜喵5 于 2014-8-4 20:27 编辑
method是定义在Object类的方法,至少在Ruby1.92中它只接收符号类的参数,所以用冒号打头传给他一个符号参数
用@command_item也可以啊,但是用了@command_item以后你在执行这个语句之前还必须令实例变量的值为一个可以转换成符号类的值,多麻烦= =
附上Ruby Doc
http://ruby-doc.org/core-1.9.2/Object.html#method-i-method
method(sym) → method
Looks up the named method as a receiver in obj, returning a Method object (or raising NameError). The Method object acts as a closure in obj’s object instance, so instance variables and the value of self remain available.
class Demo
def initialize(n)
@iv = n
end
def hello()
"Hello, @iv = #{@iv}"
end
end
k = Demo.new(99)
m = k.method(:hello)
m.call #=> "Hello, @iv = 99"
l = Demo.new('Fred')
m = l.method("hello")
m.call #=> "Hello, @iv = Fred"
作者: taroxd 时间: 2014-8-4 20:17
本帖最后由 taroxd 于 2014-8-4 20:19 编辑
喵呜喵5 发表于 2014-8-4 20:12
method(:command_item) 表示 command_item 这个方法…………
冒号表示一个符号,通常用来表示某事物的名字。你用引号 method('command_item') 也是可以的。
符号的好处在于更高的效率,以及看起来更加清晰美观。
method 是一个方法,有关它的介绍参考 F1 文档(更加建议你参考Ruby文档)。这里省略了接收者 self
也就是说,完整的写法是 self.method('command_item')。
该方法可以获得一个 method 对象,该 method 对象的接收者为当前场景(self)。
有关 method 对象的介绍,也请参考 F1(同样更加建议你参考Ruby文档)
作者: 九靈 时间: 2014-8-4 20:47
喵呜喵5 发表于 2014-8-4 20:12
method是定义在Object类的方法,至少在Ruby1.92中它只接收符号类的参数,所以用冒号打头传给他一个符号参数 ...
好吧...也许我还没理解"符号类的参数"是什么意思?
$item
@@item
@item
:item
......这些都是吗?
我只知道都是变量...
所以
m = l.method("hello")
"hello" ← 这是所谓的"容错"?
作者: taroxd 时间: 2014-8-4 20:51
九靈 发表于 2014-8-4 20:47
好吧...也许我还没理解"符号类的参数"是什么意思?
$item
@@item
$item: 全局变量
@@item: 类变量
@item: 实例变量
:item : 一个符号
对于符号的理解,就像这样。1是一个整数,"1"是一个字符串,:item是一个符号。
m = l.method("hello") 是正确传入的方式,没有什么容错之说。
只不过我们更倾向于 l.method(:hello)这种方式而已
作者: 喵呜喵5 时间: 2014-8-4 20:54
九靈 发表于 2014-8-4 20:47
好吧...也许我还没理解"符号类的参数"是什么意思?
$item
@@item
这三个是一类:$item、@@item、@item
这三个是一类:"item"、:item、12345
m = l.method("hello")
实际上是
m = l.method(("hello").to_sym)
("hello").to_sym => :hello
作者: taroxd 时间: 2014-8-4 20:56
喵呜喵5 发表于 2014-8-4 20:54
这三个是一类:$item、@@item、@item
这三个是一类:"item"、:item、12345
你为什么会产生 ruby 会调用 to_sym 的错觉
obj = Object .new
class << obj
def intern
:method
end
alias to_sym intern
end
method( obj) # TypeError
obj = Object .new
class << obj
def intern
:method
end
alias to_sym intern
end
method( obj) # TypeError
作者: 九靈 时间: 2014-8-4 21:37
本帖最后由 九靈 于 2014-8-4 21:39 编辑
感谢两位前辈
是用symbol来代表方法名吧
刚刚看到的↓
Ruby的符号
Ruby的符号足以让很多初学者迷惑上一段时间,看过本章节后,或许会解开你心中的疑惑。
在Ruby中,一个符号是就是一个Symbol类的实例,它的语法是在通常的变量名前加一个冒号,如
:my_sy
Ruby的符号像一个字符串,因为它内部表现形式是一个字符序列。而与字符串不同的是,每个符号的实例只有一个。看下面的例子:
array = ["foo", "foo", "foo", :foo, :foo, :foo]
建立这个数组后,内存中将有三个内容为"foo"的字符串对象,而只有一个:foo对象。
一个符号有它唯一对应的一个整数值,可以用to_i来获取它。
符号常用的地方是用它来代表变量名或者方法名:
class SomeClass
attr_accessor :whatever
end
与上面程序对等的程序如下:
class SomeClass
def whatever
@whatever
end
def whatever=(val)
@WHATEVER = val
end
end
你可能会问,为什么不用字符串来表示呢?其实,字符串也是可以的:
attr_reader :alpha
attr_reader "beta" # 也是合法的
那它们的区别在哪里?某种意义上来说,是为了提高程序性能,节省内存吧。
有的人说,"符号就如同不可变的字符串",从它的行为上来说,可能是对的。但是,Symbol并是是继承至String,而且,与字符串相关
的那些典型操作方法,Symbol也不一定有,也不需要有。
符号不一定看起来是像变量一样,它也可以这样:
sym1 = :"This is a symbol"
sym2 = :"This is, too!"
sym3 = :")(*&^%$"
你可以用这样奇怪的符号来定义实例变量名或方法,你可以使用诸如send或instance_variable_get来获取它们的引用。虽然是可行的,
但请尽量不要使用这么奇怪的符号。
用Symbol作为枚举
==========================================
像Pascal或版本稍晚的C语言,都存在enum这种类型。Ruby不能正真的拥有这样的类型,因为它没有类型检查。但使用Symbol可以用来产生
这样的效果:
North, South, East, West = :north, :south, :east, :west
用Symbol作为元数据
==========================================
通常我们使用捕获异常的方式来处理错误,避免使用老式的返回代码的方式。但是,如果你想用老式的方式,还是可以的。像nil就是这样一个元数据。
我们通常可以这样使用(因为符号是全局的,所以在之后的整个程序中,都可以使用这些符号来作为元数据):
str = get_string
case str
when String
# Proceed normally
when :eof
# end of file, socket closed, whatever
when :error
# I/O or network error
when :timeout
# didn't get a reply
end
Symbols, Variables, Methods
==========================================
Symbol最常用的地方就是我们熟知的定义属性了:
class MyClass
attr_reader :alpha, :beta
attr_writer :gamma, :delta
attr_accessor :epsilon
# ...
end
这里的方法,如attr_accessor,它以传入的符号来确定实例变量的名称,以及读写属性的方法的名称,但这不代表所有的情况
(即总是会自动精确匹配符号和实例变量的名称),例如,当使用instance_variable_set方法的时候,符号和实例变量名必须
精确给出:
sym1 = :@foo
sym2 = :foo
instance_variable_set(sym1,"str") # 正常,匹配到@foo
instance_variable_set(sym2,"str") # 错误
不过,记住,在这些地方不一定要使用符号,可以用字符串来替代。
转换Symbol
============================================
Symbol和字符串之间可以互相转换,使用to_s和to_sym来实现:
a = "foobar"
b = :foobar
a == b.to_str # true
b == a.to_sym # true
作者: 余烬之中 时间: 2014-8-5 08:04
基础
Symbol是一个类(符号类),以冒号打头的都是Symbol的实例(你知道类和实例是什么吧),且都是字面值(你知道字面值是什么吧?)
可以类比引号(注意只能类比),引号括起来的都是String的实例,且都是字面值
比如 "你好" 的值就是它所显示的样子
:ok 的值就是它显示的样子
如果先令 a = :ok
那么a就不是字面值 它显示的是a 但它的值是:ok
method方法和symbol的演示
class A
def m( sym)
return method( sym)
end
end
a = A.new
begin
a.m ( :n ) #=> NameError: undefined method 'n' for class 'A'
rescue
# do nothing
end
class A
def n
return "你好"
end
end
b = a.m ( :n ) #=> #<Method: A#n>
b.call #=> "你好"
class A
def m( sym)
return method( sym)
end
end
a = A.new
begin
a.m ( :n ) #=> NameError: undefined method 'n' for class 'A'
rescue
# do nothing
end
class A
def n
return "你好"
end
end
b = a.m ( :n ) #=> #<Method: A#n>
b.call #=> "你好"
与@的区别
对于符号 只要它存在 它就有值(字面值) 而且这个值不能更改
对于@变量(实例变量) 如果不事先赋值 它就是nil
所以 写法相同的符号 无论写在哪里 代表的都是同一个值
而@变量就不一定了
class A
def initialize
@ok = 1
end
def m
@ok
end
def n
:ok
end
end
class B
def initialize
@ok = 2
end
def m
@ok
end
def n
:ok
end
end
A.new .m == B.new .m #=> false
A.new .n == B.new .n #=> true
class A
def initialize
@ok = 1
end
def m
@ok
end
def n
:ok
end
end
class B
def initialize
@ok = 2
end
def m
@ok
end
def n
:ok
end
end
A.new .m == B.new .m #=> false
A.new .n == B.new .n #=> true
类变量(@@) 全局变量($)暂且不说了 他们都是可以进行赋值的
回到最初的问题
@command_window.set_handler(:item, method(:command_item))
@command_window是一个已经赋值了的实例变量 实际上 它的值是一个Window_MenuCommand类的实例 也就是菜单指令窗口
set_handler是定义在Window_MenuCommand中的实例方法 它接受两个参数 一个是符号(aSymbol) 另一个是方法(aMethod)
如果这个菜单指令窗口中某个指令被选中并确认了(每个指令都事先设置了一个符号与之对应 所以上面这个符号实际上是代表某个选项的 我们假设现在选中的指令所对应的符号是:item)
那么 由set_handler所设置的对应的方法就会被调用
这里 我们把:item和method(:command_item)关联了起来
method(:command_item)实际上是一个方法调用
method本身是一个方法 它接受一个参数 可以是符号 可以是字符串 也可以是值为符号/字符串的变量
这个方法会在当前环境中找这个参数所指定的方法 并返回这个方法 上面已经演示过了
大体就是这样
作者: 九靈 时间: 2014-8-5 10:08
余烬之中 发表于 2014-8-5 08:04
基础
Symbol是一个类(符号类),以冒号打头的都是Symbol的实例(你知道类和实例是什么吧),且都是字面值 ...
感谢
学到了个字面值
也就是 : 更安全、指向性更强兼效率,比起 $ 来讲...
欢迎光临 Project1 (https://rpg.blue/)
Powered by Discuz! X3.1