设为首页收藏本站同能贴吧 切换语言 繁体中文
开启辅助访问 切换到窄版
扫描二维码关注官方公众号
返回列表
+ 发新帖
查看: 90|回复: 0

[制作教程] Ruby's Peculiarities

[复制链接]
累计送礼:
0 个
累计收礼:
1 个
  • TA的每日心情
    开心
    前天 04:10
  • 签到天数: 209 天

    连续签到: 2 天

    [LV.7]常住居民III

    4471

    主题

    864

    回帖

    2万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    VIP
    7
    卡币
    22949
    OK点
    16
    推广点
    0
    同能卷
    50
    积分
    28314

    灌水之王

    发表于 7 天前 | 显示全部楼层 |阅读模式
    Ruby's Peculiarities

    by Kyonides


    This thread is all about some strange or unusual or certain features specific to the Ruby programming language. Some are object-oriented or functional characteristics while other are just internal specifications you should know about.

    NOTE: Parent class and Super class are synonyms here.

    Index

    • It has 5 Types of Variables
    • CONSTANTS are NOT as Static as their Counterparts in other Languages
    • Classes and Modules are ALWAYS OPEN
    • You only declare a class's parent class ONCE.
    • The Very Existence of the Eigenclass or Metaclass in Ruby
    • Modules have other ways to define NEW methods without explicitly specifying they belong to that module
    • Ruby's Boolean Values
    1. It has 5 Types of Variables


    Languages like C offer 4, namely the block, the local, and 2 kinds of global variables.

    C++ has the static and global static variables, too. The static variables behave in a similar way as Ruby's class variables.
    [ Global static variables only exist on the C or C++ file where they were declared. ]

    Ruby includes the instance variables, but lacks the global static variables.

    From Ruby you get: $global, @@class, @instance, local and block.

    Yes, the last 2 variables have no special symbol attached to them. The context determines which type of variable it is. Block variables can only live inside loops and iterators.

    2. CONSTANTS are NOT as Static as their Counterparts in other Languages


    In most languages, constants are always written in UPPERCASE. Sometimes their names might include some _underscore_ symbols as well.

    In C or C++, you are NEVER supposed to alter a constant during execution.

    On the contrary, Ruby does allow you do change them. This is specially true for Arrays [] and Hashes {}. Yet, you might want to use @instance variables instead. This would force you to create specific getter and setter methods in order to let you access or modify their values.

    Then why would anybody let you alter a CONSTANT in the first place?

    Well, the answer to this question might be found in our next point.

    3. Classes and Modules are ALWAYS OPEN


    Both classes and modules need a name, and it's a Constant by nature.

    Did you notice that I didn't write it in ALL CAPS?

    That's because you're NOT supposed to. Only normal CONSTANTS need to follow that nomenclature. Class or Module names follow the same convention used in C++ for classes and namespaces, respectively.

    Contrary to what happens to the other CONSTANTS' behavior, these Constants are not altered directly. You can only alter its contents, including its eigenclass or metaclass.

    Just like it happens in other languages, you need to declare a class or module first.

                    Ruby:        
    class MyClass end  module MyModule   def self.my_method     print "My method"   end end


    Call MyModule.my_method and a popup window will display this message: "My method"

    Once they've been declared, they'll keep existing until the program finishes its execution.

    Classes in Ruby can ONLY inherit methods declared in 1 parent class at a time. This limitation doesn't prevent the parent class to have its own superclass (a synonym) and this dynamic can repeat itself indefinitely. At the end, a class can inherit tons of methods from multiple classes as long as they all belong to the same family of classes.

    This means a given class would only follow 1 single path up to the most basic class Object in Ruby 1.8 and 1.9 or BasicObject in Ruby 2.x and 3.x and that's it.

    In C++ you can declare many friend classes simultaneously while Ruby cannot.

    How might this affect the way Constants work in Ruby as I've mentioned in the previous point?

    Well, these Constants cannot be closed. Not even once. You might finish defining a list of methods or singleton methods by placing the very last end keyword at the end of that script, but the class isn't closed internally. You can only close the definition stage, not the class itself.

    You can easily confirm this. Just reopen that class or module in a separate script section and it will still work as long as you have not committed any errors.

    That means I can now extend MyClass this way:

                    Ruby:        
    class MyClass   def first_method     print "First"   end end


    I can either paste it right below my previous declaration or on another script section, and nothing weird will ever happen.

    What this proves is that Ruby classes and modules can be extended INDEFINITELY. (Or until you get out of RAM...)

    And here comes another revelation that many old scripters loved to ignore:

    4. You only declare a class's parent class ONCE


    It doesn't mean that you can't declare it 1000 times if that's what you really want to do. The problem is you have NO NEED to do that, so why bother?

                    Ruby:        
    class MyChildClass < MyClass   def second_method     print "Second"   end end


    So far I have only declared 1 method MyChildClass, but don't forget you can also call MyClass#first_method as well. Why? Because it has been inherited from MyClass.

    [ MyClass#first_method is not proper syntax, it's just a way Ruby programmers indicate where you can actually find that method. You're supposed to replace MyClass# with nothing if called from a class's internal method or with an actual object like @my_class.first_method ]

    Still, what happens if later on I wanna add a third method? Especially on a different script...

    Well, I can do this without facing any consequences:

                    Ruby:        
    class MyChildClass   def third_method     print "Third"   end end


    So why was I allowed to keep defining new methods if I NEVER redeclared the parent class?

    The answer is very simple: the class is still open and it DOES REMEMBER its superclass!

    In Ruby 1.8 and 1.9 you're even allowed to change an existing class's parent class by redeclaring that superclass. Nonetheless, stop doing that! In later releases of the Ruby language it's considered a BUG and you're NOT ALLOWED to redeclare a parent class at all. Your session would crash immediately.

    Of course, I know some people wouldn't care about changes applied to Ruby in later releases of the language, and I get it. The problem is that your code is supposed to follow a logic, an order. Changing a class's parent class definitely breaks that. Plus, it makes it way harder for other scripters to foresee such a change because they're used to the way the default scripts have been defined by the RPG Maker developers. If a scripter expects to access methods defined in the original parent class, the game will crash during test play.

    Instead of changing the declaration of a class's superclass, just go create a new class with its own parent class, and case closed.

    5. The Very Existence of the Eigenclass or Metaclass in Ruby


    Because of the ability to declare singleton methods, methods that can only be accessed via the class or module itself instead of an instance (a copy) of a class, Ruby has the need to store all those class- or module-specific methods somewhere else. That other place is the eigenclass or metaclass.

    By the way, eigen means "own" or "proper" in German, but in this particular case proper is the term we're looking for here. The eigenclass is the real class behind the actual class, if that makes any sense to you.


    How do you access such an internal class?

    Actually you might have already seen it in 2 different contexts: some scripter was altering a module or the Bitmap class.
    You can rarely watch someone else altering some other class this way:

                    Ruby:        
    class << Bitmap end  module << Graphics   def width     640   end end


    What has changed after accessing the eigenclass this way?

    The changes are reduced to 1 simple concept: you can now define any methods or even Module class's methods like attr_accessor the same way you'd do it in any normal class. Yes, you can easily alias methods as well.

    Except for the use of this << operator, everything else would look and behave as business as usual.

    6. Modules have other ways to define NEW methods without explicitly specifying they belong to that module


    This alternate method defining processes might not work with previously defined methods that included the self keyword.

    Let's assume the default scripts included this module (or just add it to your script list):

                    Ruby:        
    module OldModule   def self.method     print "method"   end end


    And later on we try to redefine it or alias it this way:

                    Ruby:        
    module OldModule   extend self   def method     print "method revisited"   end end


    Normally, we would use extend to extend a class or another module, but Ruby also allows us to extend the same module, too. Classes are not supposed to extend themselves.

    Or let's use any of these 2 other ways:

                    Ruby:        
    module OldModule   module_function   def method     print "method revisited"   end end


                    Ruby:        
    module OldModule   def method     print "method revisited"   end   module_function :method end


    There's a big chance that those new definitions might not work as expected. :S They can even be ignored by the language interpreter.

    If you want to redefine them, you better use the self.method definition at all costs.
    Or go straight to the eigenclass and redefine it there or simply go alias that method.

    7. Ruby's Boolean Values


    If you really ever wanted to find something terribly weird in a programming language, then the way Ruby implemented the boolean values might fit the bill.

    In Ruby there are not 2 but 3 boolean values. The typical values are true or false. Yet, Ruby added nil to this list. It treats it as a second false value. Most of the time at least.

    Nil or nihil means nothing in Latin. Ruby only calls it nil, and it has the same basic usage as a null in C or C++ except for a little detail I'll discuss later on.

    When is nil treated as an actual nil or non existing value?

    That happens ONLY when you test a value against nil itself!


                    Ruby:        
    @variable == nil


    If it returns true, it means it was really equal to nil in the first place. If you have never defined it before, then its current value is equal to nil. (It simply creates it then, and quickly sets its value to nil.)

    nil is quite weird

    If you define a variable the following way using the || or-operator:

                    Ruby:        
    @var = nil || false


    It won't return a nil but a false value!


    Defining a variable with an ||= if-not-yet-defined-set-value operator:
                    Ruby:        
    @var ||= nil


    It becomes a redundant piece of code because that's exactly what Ruby would have done in the first place.


    In languages like C and C++, you can use numeric values like 1 and 0 as replacements for true and false respectively. That's not possible in Ruby.

    Ruby treats ALL NUMBERS (and objects except for false and nil) as true if you test them directly or via calling a variable.

                    Ruby:        
    if 0   print "Zero is treated as a truthy value." else   print "You'll never read this line ever." end


    Nevertheless, that won't be case if you explicitly test it against true:

                    Ruby:        
    if 0 == true   print "Zero is treated as a truthy value... but not here!" else   print "You'll read this line in no time. Guaranteed!" end


    So numbers are treated and NOT treated as truthy values depending on the current context. :S


    本贴来自国际rpgmaker官方论坛作者:kyonides处,因国际论坛即将永久关站,为了存档多年珍贵资料,署名转载到本论坛存档,由于官方帖子为英文原帖,需要中文翻译请点击论坛顶部切换语言为中文就可以将帖子翻译成中文浏览,方便大家随时查看,原文地址:https://forums.rpgmakerweb.com/threads/rubys-peculiarities.180059/

    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有账号?立即注册

    x
    天天去同能,天天有童年!
    回复 送礼论坛版权

    使用道具 举报

    文明发言,和谐互动
    文明发言,和谐互动
    高级模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    简体中文
    繁體中文
    English(英语)
    日本語(日语)
    Deutsch(德语)
    Русский язык(俄语)
    بالعربية(阿拉伯语)
    Türkçe(土耳其语)
    Português(葡萄牙语)
    ภาษาไทย(泰国语)
    한어(朝鲜语/韩语)
    Français(法语)
    关闭

    幸运抽奖

    社区每日抽奖来袭,快来试试你是欧皇还是非酋~

    立即查看

    聊天机器人
    Loading...

    QQ|Archiver|手机版|小黑屋|同能RPG制作大师 ( 沪ICP备12027754号-3 )

    GMT+8, 2026-7-14 18:01 , Processed in 0.066821 second(s), 56 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

    快速回复 返回顶部 返回列表