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

[转载] Slip into Ruby Resurrected!

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

    连续签到: 2 天

    [LV.7]常住居民III

    4446

    主题

    864

    回帖

    2万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

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

    灌水之王

    发表于 7 天前 | 显示全部楼层 |阅读模式
    Since rpgmaker.net went down, so unfortunately have all my Slip into Ruby and Jump into Javascript articles. However, rejoice, sports fans! I'm bringing them all back right here. To prevent clutter, I will make each article its own reply to this thread. If you can think of a better way for me to do it, I am entirely ears. Without further ado, let's begin!

    SLIP INTO RUBY PART 1 - OBJECT-ORIENTED WHA?​

    Part 1 of a series explaining Ruby and RGSS in a way you can understand.

    Hello folks, and welcome to part 1 of...






    My goal is to offer a resource to budding RMXP/VX/VX Ace users who know that there's a scripting language there but don't have the first idea what it is or how to use it. Or people who DO have a first idea but aren't quite getting it.

    However, before we can really get into the meat of what RGSS is and can do, it makes more sense to take a look at it from a wider viewpoint. So we're going to start with a bit of a primer on what, exactly, object-oriented programming is.

    I could talk about classes and methods and properties and instance variables and inheritance and parameters and arguments until I'm blue in the face, but I know there are some people out there who wouldn't have a clue what I was on about. So we're going to make a cat instead.

    If you're starting with a blank slate, you can't ask Ruby for a cat, because it has no idea what one is. Before we can make one, we need to provide a template from which all cats will be manufactured; a blueprint for a cat, if you will. In Ruby, this template is called a “class”:

                    Ruby:        
    class Cat end


    This is one of the simplest classes you can write. It's the minimum amount of code required to be able to say “Hey Ruby, give me a cat please.” If at some point we find ourselves in need of a cat, it's simple: all we have to do is create a new instance of Cat with a unique name, like so:

                    Ruby:        
    tiddles = Cat.new


    We now have a cat, but it isn't a very exciting one because it just sort of sits there and doesn't do much. However, there is one thing it did that you couldn't see; it called its constructor method (“method” being Ruby's term for a subroutine or function)

    The constructor method is a specially-named one which is always called “initialize” and is always called as soon as an instance of the class is created; if you don't provide one explicitly, there's a built-in one for all classes which Ruby will call for you, but this isn't always ideal if we want to do anything specific when we make a new cat. We'll come back to this later, so don't worry too much about it right now.

    The main concern we have at the moment is that the cat can't breathe, which means it isn't going to live very long unless we give it some way to do so. Let's do that quickly before our pet expires:

                    Ruby:        
    class Cat   def breathe     #insert code for inhaling oxygen and exhaling CO2   end end


    There we go. Now any instance of a cat is able to breathe by calling this method when it's needed in the program. You call a method by entering the name of the instance, followed by a period, followed by the method name, like so:

                    Ruby:        
    tiddles.breathe


    And our moggy lives to see another day. However, as you can see it's still not the most exciting of pets...maybe we'd have more luck with a dog?

                    Ruby:        
    class Dog end  rover = Dog.new  rover.breathe


    Uh oh. Rover's just informed us that he can't find a method called “breathe”, and he's rapidly turning blue. What went wrong?

    Well a dog isn't a cat, so dogs can't really do anything that cats can. If we want Rover to breathe, we need to add the method to his class too:

                    Ruby:        
    class Dog   def breathe     #code for breathing   end end


    There we go, much better. But Rover's just as boring as Tiddles. And the fact that we've replicated the exact same code bothers me. If only there were some way our cat and dog could share the breathing method between them...

    Here's where class inheritance comes in. See, classes can be children of other classes, and the great thing is they will inherit all of the properties and methods of their parent. What do cats and dogs have in common? They're animals. What do all animals do? Breathe. So rather than replicating the breathe method for every animal in the world, it'll be much easier to let animals in general do the breathing and then pass it on to cats and dogs via inheritance. And we do that like so:

                    Ruby:        
    class Animal   def breathe     #code for breathing   end end  class Cat < Animal end  class Dog < Animal end


    Excellent! Now we can do

                    Ruby:        
    tiddles.breathe rover.breathe


    And our pets have no respiratory problems whatsoever. We could even give ourselves a goldfish and as long as we specified that he's an animal too he can breathe like the rest. Of course, fish don't breathe quite the same way as cats and dogs, but that's a topic for later.

    I feel quite sorry for poor Tiddles and Rover, so my next task is to give them a way to communicate with me. Let's see...

                    Ruby:        
    class Animal   def breathe     #code for breathing   end      def meow     print “Meow!”   end    def bark     print “Woof!”   end end


    So now we can do:

                    Ruby:        
    tiddles.meow rover.bark


    And our output on the screen would be:

                    Code:        
    Meow! Woof!


    But wait. Inheritance isn't always a good thing...

                    Ruby:        
    tiddles.bark rover.meow


    Yeah, sometimes animals just need to have their own sounds. Let's fix this:

                    Ruby:        
    class Animal   def breathe     #code for breathing   end end  class Cat < Animal   def meow     print “Meow!”   end end  class Dog < Animal   def bark     print “Woof!”   end end


    There we go, now dogs can only bark and cats can only meow. Our pets are able to communicate and breathe. They're starting to look much better already!

    So tell me, how old is Tiddles? What? You don't know? Why not?

    Well we haven't even told Ruby that our furry friends have ages. In fact it doesn't even know they're furry because we haven't told them about fur either. Things like this are called properties, and determine the kinds of data that can be held about the class.

    So that we can answer the above question, let's give animals an age property. All animals have an age, so we might as well make it common to any animals we need. There are several ways to do this; I'll show you the least abusable way, then explain the alternative and tell you why it's a bad idea.

                    Ruby:        
    class Animal   def initialize     @age = 0   end    def breathe     #code for breathing   end    def age     @age   end    def age=(val)     @age = val   end end


    Oh man, that's a bit more complicated than we're used to so far, but don't worry, it's pretty simple. The “@” is basically telling Ruby that this variable is an “instance variable”--that is to say that every new instance of the class will have its own version. This means that Tiddles the cat will have an age independent from that of Felix the cat. If we didn't denote it as an instance variable then all cats would share an age, and that would just be chaos.

    The new methods are there so that we can find out the age of a cat, or change its age if needed. So now when I ask you “How old is Tiddles?” you need only enter this in your program:

                    Ruby:        
    tiddles.age


    And the returned value will be the age of Tiddles. You can also do

                    Ruby:        
    tiddles.age=5


    And Tiddles will magically age to 5 years old.

    This is, in my opinion, the best way to do this. What you could have done was this:

                    Ruby:        
    class Animal   attr_accessor    :age   def initialize     @age = 0   end    def breathe     #code for breathing   end end


    “attr_accessor”, “attr_reader” and “attr_writer” are essentially a shorthand way of doing the get and set methods we created in the previous example, but there's one important difference. attr_accessor basically means the variable can be read or written to at any time by anything anywhere. This might result in you accidentally changing a cat's age in a part of your program that has nothing to do with cats, and if you don't realise you've done it that's going to be a  to find and debug later.

    The way we did it was by creating what are known as “getter” and "setter" methods, which allow you to read and write instance variables but only from within their own class, limiting the circumstances under which one might change a variable's value without meaning to.

    So now we have a parent class, Animal, which determines the things an animal is able to do. We might end up adding other methods to this like jump, swim, mate and so on. Then for the cat class, we might add catch_mice, scratch_human, land_gracefully...you get the idea.

    You may have caught on to something I mentioned earlier when I said that some animals might not breathe the same way as others. Fish certainly don't breathe the same way cats do, but currently if you made fish an animal the program wouldn't know that. We'd have to do what's called “overloading” and give fish their own, unique way to breathe. We simply do that by redefining the breathe method in the fish class:

                    Ruby:        
    class Fish < Animal   def breathe     #insert custom code that only applies to fish   end end


    Now although fish inherit methods from Animal, we've told the program that they breathe differently from other types. Basically a method's functionality will be determined by the lowest level at which it's defined: methods in a specific class will take precedence over the parent, which will take precedence over the containing module (we'll cover modules later, don't worry).

    And that's really all you need to know to be able to start recreating the world in Ruby! These concepts are the only things necessary to model the everyday things you see around you--and, indeed, kickass RPG systems. That's why you're here, right?

    Recap:


    • Classes are the “templates” used to create an object.
    • Methods are the functions/subroutines that determine what the class can do.
    • Properties are pieces of data that describe the class.
    • Classes can be children of other classes, and will inherit any properties or methods the parent has in addition to its own.
    • Properties can be read/written either by creating getter/setter methods, or designating them as one of “attr_accessor”, “attr_reader” or “attr_writer”. Note that attr_accessor will allow reading and writing, attr_reader will be read-only and attr_writer will be write-only.
    • If a module, class or subclass have methods with the same name, the one that's lowest in the hierarchy will be used. Redefining a method that was already defined further up the chain is called “overloading”.
    That's it for part 1 of Slip into Ruby! Feel free to tell me what you think; please let me know if I've said anything that's inaccurate or I missed something out in my explanations that would be useful.

    In part 2 I'm intending to cover properties in more detail, including the different kinds of variable, and possibly go into parameters and arguments. If there's anything else you'd like an explanation on please let me know and I'll cover it either in part 2 or a later one.

    ------

    Phew! The formatting needed some fixing from its original form, so I think I'm just gonna post these once a day rather than doing them all in one go. If you'd rather have them faster, though, I'm sure I can figure something out!

    (Mods, if you could pin this, that'd be awesome, since it's intended as a replacement to the current pinned thread)


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

    本帖子中包含更多资源

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

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

    使用道具 举报

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

    本版积分规则

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

    幸运抽奖

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

    立即查看

    聊天机器人
    Loading...

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

    GMT+8, 2026-7-14 14:20 , Processed in 0.179241 second(s), 56 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2020, Tencent Cloud.

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