Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby 为什么可以';我不能在Integer类中覆盖self吗?_Ruby_Class_Metaprogramming - Fatal编程技术网

Ruby 为什么可以';我不能在Integer类中覆盖self吗?

Ruby 为什么可以';我不能在Integer类中覆盖self吗?,ruby,class,metaprogramming,Ruby,Class,Metaprogramming,我想能够写number.incr,就像这样: num=1;数量增加;号码 #=>2 我看到的错误是: 无法更改self的值 如果那是真的,那你怎么办!方法有效吗?根本不可能将自己改变成另一个对象self是发送消息的接收者。只能有一个 如果那是真的,那你怎么办!方法有效吗 bang(!)只是方法名称的一部分。绝对没有什么特别的意义。Ruby程序员习惯于用“砰”的一声命名不那么令人惊讶的方法的令人惊讶的变体,但这只是一种习惯。根本不可能将self更改为另一个对象self是发送消息的接收者。只能有一个

我想能够写
number.incr
,就像这样:

num=1;数量增加;号码
#=>2

我看到的错误是:
无法更改self的值


如果那是真的,那你怎么办!方法有效吗?

根本不可能将自己改变成另一个对象
self
是发送消息的接收者。只能有一个

如果那是真的,那你怎么办!方法有效吗


bang(
)只是方法名称的一部分。绝对没有什么特别的意义。Ruby程序员习惯于用“砰”的一声命名不那么令人惊讶的方法的令人惊讶的变体,但这只是一种习惯。

根本不可能将
self
更改为另一个对象
self
是发送消息的接收者。只能有一个

如果那是真的,那你怎么办!方法有效吗

bang(
)只是方法名称的一部分。绝对没有什么特别的意义。Ruby程序员习惯于用“砰”的一声命名不那么令人惊讶的方法的令人惊讶的变体,但那只是一种习惯。

你不能改变self的值 对象是一个(请注意,此链接是Ruby的旧版本,因为它非常简单,因此更好地用于解释目的)

“指向”一个对象意味着你有一个变量,它将对象的位置存储在内存中。然后,要对该对象执行任何操作,您首先要转到内存中的位置(我们可以说“跟随指针”)获取该对象,然后执行该操作(例如,调用一个方法,设置一个ivar)

所有Ruby代码都在某个对象的上下文中执行。这是保存实例变量的地方,也是Ruby查找没有接收器的方法的地方(例如,
$stdout
$stdout.puts“hi”
中的接收器,当前对象是
puts“hi”
中的接收器)。有时需要对当前对象执行某些操作。使用对象的方法是通过变量,但哪些变量指向当前对象?没有。为了满足这一需求,提供了关键字
self

self
的作用类似于一个变量,因为它指向当前对象的位置。但它不像一个变量,因为你不能给它赋值。如果可以的话,在这一点之后的代码会突然在另一个对象上运行,这会让人感到困惑,并且与仅仅使用变量相比没有任何好处

还要记住,对象是由存储内存地址的变量跟踪的。
self=2
应该是什么意思?这是否仅仅意味着当前代码的操作就好像它是被调用的
2
?或者这意味着所有指向旧对象的变量的值现在都更新为指向新对象?这并不十分清楚,但前者不必要地引入了身份危机,而后者的成本高得让人望而却步,并且引入了不清楚什么是正确的情况(我将在下面进一步讨论)

你不能变异Fixnums 在Ruby中的C级别是特殊的(false、true、nil、fixnums和Symbol)

指向它们的变量实际上并不存储内存位置。相反,地址本身存储对象的类型和标识。无论在什么地方,Ruby都会检查它是否是一个特殊的对象(例如何时),然后从中提取值

因此,内存中没有存储对象
123
的位置。这意味着
self
包含了Fixnum
123
的概念,而不是像通常那样的内存地址。与变量一样,它将在必要时进行检查和特殊处理

因此,您无法改变对象本身(尽管它们似乎保持不变,以允许您在符号等对象上设置实例变量)

他们为什么要这么做?为了提高性能,我假设。存储在寄存器中的数字只是一系列位(通常为32或64位),这意味着存在用于加法和乘法之类的硬件指令。也就是说,ALU被连接在一个时钟周期内执行这些操作,而不是用软件编写算法,这将花费许多数量级的时间。通过这样存储它们,它们避免了在内存中存储和查找对象的成本,并且获得了可以使用硬件直接添加两个指针的优势。然而,请注意,Ruby中仍然存在一些C中没有的额外成本(例如,检查溢出并将结果转换为Bignum)

爆炸法 你可以在任何方法的末尾加上一记重击。它不需要改变对象,只是当你做一些可能产生意外副作用的事情时,人们通常会试图警告你

class C
  def initialize(val)
    @val = val         # => 12
  end                  # => :initialize

  def bang_method!
    "My val is: #{@val}"  # => "My val is: 12"
  end                     # => :bang_method!
end                       # => :bang_method!

c = C.new 12    # => #<C:0x007fdac48a7428 @val=12>
c.bang_method!  # => "My val is: 12"
c               # => #<C:0x007fdac48a7428 @val=12>
选择
  • 制作一个包装器对象:我不打算提倡这个,但它最接近您要做的。基本上创建您自己的类,它是可变的,然后使它看起来像一个整数。这里有一篇很棒的博客文章,在这里浏览一下,你会有95%的收获
  • 不要直接依赖于Fixnum的价值:如果不知道你想做什么/为什么你觉得这是一种需要,我就不能给出比这更好的建议

另外,当你问这样的问题时,你应该展示你的代码。很长一段时间以来,我误解了你是如何接近它的。

你不能改变自我的价值观 对象是一个(请注意,此链接是Ruby的旧版本,因为它非常简单,因此更好地用于解释目的)

“指向”一个对象意味着你有一个变量,它将对象的位置存储在内存中。然后,要对对象执行任何操作,首先要转到内存中的位置(我们可以说“跟随指针”),以获取
Fixnum.instance_methods.grep(/!$/)  # => [:!]

# Okay, there's one, but it's actually a boolean negation
1.!  # => false

# And it's not a Fixnum method, it's an inherited boolean operator
1.method(:!).owner  # => BasicObject

# In really, you call it this way, the interpreter translates it
!1  # => false