ruby中argv_Ruby中的猴子修补简介

ruby中argv

Monkey Patching consists of “dynamic modifications of a class or module at runtime, motivated by the intent to patch existing third-party code as a workaround to a bug or feature which does not act as desired,” hence, a monkey patch would not change the software itself, but only the local copy while it’s being run.

猴子修补程序包括“在运行时动态修改类或模块,其目的是为了修补现有的第三方代码,以作为无法正常工作的错误或功能的解决方法”,因此,猴子修补程序不会更改软件本身,但仅是运行时的本地副本。

In everyday terms, monkey patching changes the behavior of class methods (built-in or user created) at runtime. For someone beginning to learn programming this might seem like a lot to digest, but it isn’t (I promise)!

日常而言,猴子修补会在运行时更改类方法(内置或用户创建)的行为。 对于开始学习编程的人来说,这似乎需要消化很多,但这不是(我保证)!

Every class in Ruby has its own list of built-in methods. For example, a string has a whole list of methods: including #reverse which will reverse the order of the string, #count which will count how many characters are in the string, #empty? which will tell you whether the string is empty or not by returning true or false, and on and on…

Ruby中的每个类都有自己的内置方法列表。 例如,字符串具有完整的方法列表:包括#reverse和#county,它们将颠倒字符串的顺序; #count将计算字符串中有多少个字符; #empty? 它将通过返回true或false并不断地告诉您字符串是否为空。

You get the idea––Ruby has a lot of built-in methods. How about we try to monkey patch one of these built-in string methods to show how easy and powerful monkey patching actually is? Let’s go over what we know first:

您知道了– Ruby有很多内置方法。 我们如何尝试对这些内置字符串方法之一进行猴子修补,以显示猴子修补实际上是多么容易和强大? 让我们回顾一下我们首先了解的内容:

Image for post

Pretty simple stuff, right? Now let’s call the #clear function…

很简单的东西,对不对? 现在让我们调用#clear函数...

Image for post

As expected, the string is cleared and test now contains an empty string. But what if we could change the way the String#clear method works? Instead of clearing the array, let’s have it print a new string that repeats itself.

正如预期的那样,该字符串已清除,并且测试现在包含一个空字符串。 但是,如果我们可以更改String#clear方法的工作方式,该怎么办? 不用清除数组,而是让它打印一个重复其自身的新字符串。

Image for post

Now, how do we give the class of string access to this new String#clear method? You might think we’d probably need to spend a bunch of time sorting through the Ruby libraries on your system and alter this method, right? Wrong!

现在,我们如何让字符串类访问此新的String#clear方法? 您可能会认为我们可能需要花费大量时间来对系统上的Ruby库进行排序并更改此方法,对吗? 错误!

We just need to create a new class of String and drop our method in.

我们只需要创建一个新的String类并放入我们的方法即可。

Image for post

This new String#clear method will overwrite the existing String#clear method built into Ruby on our system as long as it is included in the project we are currently working on.

这个新的String#clear方法将覆盖我们系统上内置于Ruby中的现有String#clear方法,只要该方法包含在我们当前正在处理的项目中即可。

That means this is not a permanent change that will affect any of our other projects––it will only be available if the file is included in a Ruby project by explicitly writing the below:

这意味着这不是一个永久性的更改,不会影响我们的任何其他项目-只有通过明确编写以下内容,该文件才包含在Ruby项目中,该更改才可用:

Image for post

We now have our new String#clear method ready to go, let’s give it a try.

现在,我们可以使用新的String#clear方法了,让我们尝试一下。

Image for post

The #clear method no longer performs its default behavior. Pretty amazing, huh? Not only can you change the behavior of an existing method, you can also create your own to be performed on a class.

#clear方法不再执行其默认行为。 太神奇了吧? 您不仅可以更改现有方法的行为,还可以创建自己的类来执行。

For instance, Rails has an array method that extends the array class to transform an array into a sentence (Array#to_sentence). What if you really wanted to use this method, but you didn’t necessarily need the rest of what Rails provides?

例如,Rails具有一个数组方法,该方法扩展了数组类以将数组转换为句子( Array#to_sentence )。 如果您确实想使用此方法,但不一定需要Rails提供的其余内容,该怎么办?

Just copy the source code of the method from the Rails documentation, place it into an array class like we did to the String class above, and voilà!

只需从Rails文档中复制该方法的源代码,然后像上面对String类所做的那样将其放入一个数组类中,那就太麻烦了!

Image for post
Source of Array#to_sentence from apidock.com
来自apidock.com的Array#to_sentence的来源

With all that being said, monkey patching is something that we will seldom have to use or implement manually (Rails monkey patches methods into the default Ruby library for us). In some languages, namely Python, monkey patching is strongly discouraged. Ruby has seemed to embrace it more than others but you should know it does come with its own pitfalls.

话虽如此,猴子补丁是我们很少需要手动使用或实现的事情(Rails猴子补丁方法对我们来说是默认的Ruby库)。 在某些语言(即Python)中,强烈建议不要进行猴子修补。 Ruby似乎比其他人更喜欢它,但是您应该知道它确实有其自身的陷阱。

Changing the default behavior of methods can produce very unexpected and hard to solve bugs. Altering a built-in Ruby method’s behavior (even in a small way) can create catastrophic results, especially when developing in teams.

更改方法的默认行为会产生非常出乎意料且难以解决的错误。 更改内置Ruby方法的行为(即使以很小的方式)也会产生灾难性的结果,尤其是在团队开发中。

Just imagine the bugs other developers would encounter if you had Array#count enumerate in a one-based system as opposed to the default zero based. A ridiculous example but you get the idea.

试想一下,如果您在基于1的系统中枚举Array#count而不是基于默认的基于零的枚举,其他开发人员将会遇到的错误。 一个荒谬的例子,但您明白了。

In some cases, though it might be the cleanest option or a temporary fix to a bug that hasn’t been updated by that framework’s developers yet, it shouldn’t be your fix-all to a tough problem; it’s a tool at your disposal, but should be used sparingly and/or with great care.

在某些情况下,尽管它可能是最干净的选择,或者是对该框架的开发人员尚未更新的bug的临时修复,但它不应该是解决一个棘手问题的全部; 它是您可以使用的工具,但应谨慎使用和/或谨慎使用。

To quote Phillip Brown, whose blog post helped me gain a better understanding of this concept, “Ruby is like a sharp knife, it can be extremely effective, but it’s usually your own fault if you cut yourself.”

引用菲利普·布朗 ( Phillip Brown )的话说,他的博客文章帮助我更好地理解了这个概念:“ Ruby就像一把利刃的刀,可能非常有效,但是如果您割伤自己,通常是您自己的错。”

翻译自: https://medium.com/@wardprice/what-is-monkey-patching-a4fd58bb8d39

ruby中argv

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在Linux内核,也有一个函数叫做`argv_split`,它用于将用户空间传递给内核的命令行参数字符串分割成多个子字符串。在内核,这个函数通常用于解析用户空间传递的命令行参数,并将它们作为参数传递给系统调用或驱动程序。 `argv_split`函数的实现与用户空间的实现略有不同,因为内核不能使用标准库函数。下面是一个简化版的内核实现: ```c #include <linux/string.h> #define MAX_ARGS 32 static char *argv[MAX_ARGS]; int argv_split(char *str, char **argbuf, int argbuf_len) { int argc = 0; char *s = str; char *arg = NULL; int arg_len = 0; int in_quotes = 0; int i; while (*s) { if (argc == argbuf_len) return -1; if (*s == '"') { in_quotes = !in_quotes; } else if (*s == ' ' && !in_quotes) { arg = kmalloc(arg_len + 1, GFP_KERNEL); if (!arg) return -1; memcpy(arg, str, arg_len); arg[arg_len] = '\0'; argbuf[argc++] = arg; str = s + 1; arg_len = 0; } else { arg_len++; } s++; } if (arg_len) { arg = kmalloc(arg_len + 1, GFP_KERNEL); if (!arg) return -1; memcpy(arg, str, arg_len); arg[arg_len] = '\0'; argbuf[argc++] = arg; } for (i = 0; i < argc; i++) argv[i] = argbuf[i]; argv[argc] = NULL; return argc; } ``` 该函数接收一个字符串`str`,以及一个指向存储子字符串的缓冲区的指针`argbuf`和缓冲区的长度`argbuf_len`。函数会将`str`的子字符串分割成多个部分,并将它们存储在`argbuf`。如果`argbuf`不够大,函数将返回-1。 注意,由于该函数运行在内核态,因此不能使用标准库函数。在上面的实现,我们使用了Linux内核提供的`kmalloc`函数来分配内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值