为了账号安全,请及时绑定邮箱和手机立即绑定

为什么Ruby设置者需要“Self”班里的资格?

/ 猿问

为什么Ruby设置者需要“Self”班里的资格?

Cats萌萌 2019-06-11 13:44:33

为什么Ruby设置者需要“Self”班里的资格?

Ruby setter-是否由(c)attr_accessor或者手动-似乎是唯一需要的方法self.在类本身内访问时的限定条件。这似乎使Ruby单独进入了语言世界:

  • 所有方法都需要

    self/this

    (比如Perl,我认为Javascript)
  • 不需要任何方法

    self/this

    IS(C#,Java)
  • 只有策划者才需要

    self/this

    (红宝石?)

最好的比较是C#与Ruby,因为两种语言都支持语法上像类实例变量一样工作的访问器方法:foo.x = yy = foo.x..C#称它们为属性。

下面是一个简单的例子;Ruby中的同一个程序,然后是C#:

class A  def qwerty; @q; end                   # manual getter
  def qwerty=(value); @q = value; end   # manual setter, but attr_accessor is same 
  def asdf; self.qwerty = 4; end        # "self." is necessary in ruby?
  def xxx; asdf; end                    # we can invoke nonsetters w/o "self."
  def dump; puts "qwerty = #{qwerty}"; endenda = A.new
a.xxx
a.dump

拿走self.qwerty =()并且失败了(Linux&OSX上的Ruby1.8.6)。现在C#:

using System;public class A {
  public A() {}
  int q;
  public int qwerty {
    get { return q; }
    set { q = value; }
  }
  public void asdf() { qwerty = 4; } // C# setters work w/o "this."
  public void xxx()  { asdf(); }     // are just like other methods
  public void dump() { Console.WriteLine("qwerty = {0}", qwerty); }}public class Test {
  public static void Main() {
    A a = new A();
    a.xxx();
    a.dump();
  }}

问:这是真的吗?除了策划人以外,还有其他需要自我的场合吗?也就是说,在其他情况下,Ruby方法不可能被调用赛尔夫?

当然,在很多情况下,赛尔夫是必要的。这并不是Ruby独有的,只是要明确一点:

using System;public class A {
  public A() {}
  public int test { get { return 4; }}
  public int useVariable() {
    int test = 5;
    return test;
  }
  public int useMethod() {
    int test = 5;
    return this.test;
  }}public class Test {
  public static void Main() {
    A a = new A();
    Console.WriteLine("{0}", a.useVariable()); // prints 5
    Console.WriteLine("{0}", a.useMethod());   // prints 4
  }}

同样的歧义是以同样的方式解决的。但我想问的是这个案子

  • 一种方法

    被定义,和
  • 已经定义了局部变量,并且

我们遇到

qwerty = 4

这是一个方法调用还是一个新的局部变量赋值?



查看完整描述

3 回答

?
浮云间

这里需要记住的重要一点是,Ruby方法可以在任何时候定义(Un),因此要智能地解决歧义,每个赋值都需要运行代码来检查在赋值时是否有指定名称的方法。


查看完整回答
反对 回复 2019-06-11
?
慕斯王

我觉得这是因为qwerty = 4是模棱两可的-您是否定义了一个名为qwerty或者打电话给策划人?Ruby通过说它将创建一个新变量来解决这个歧义,因此self.是必需的。

这是你需要的另一个案例self.:

class A  def test    4
  end
  def use_variable
    test = 5
    test  end
  def use_method
    test = 5
    self.test  endenda = A.new
a.use_variable # returns 5a.use_method   # returns 4

如您所见,访问test是模棱两可的,所以self.是必需的。

这也是为什么C#示例实际上不是一个很好的比较的原因,因为使用setter定义变量的方式是明确的。如果在C#中定义了与访问器同名的变量,则需要将对访问器的调用限定为this.就像Ruby的案子一样。


查看完整回答
反对 回复 2019-06-11
?
料青山看我应如是

否则,就不可能在方法内部设置局部变量。variable = some_value是模棱两可的。例如:

class ExampleClass
  attr_reader :last_set  def method_missing(name, *args)
    if name.to_s =~ /=$/
      @last_set = args.first    else
      super
    end
  end

  def some_method
    some_variable = 5 # Set a local variable? Or call method_missing?
    puts some_variable  endend

如果self并不是策划人所必需的,some_methodNameError: undefined local variable or method 'some_variable'..不过,与-现在一样,该方法的工作原理是:

example = ExampleClass.new
example.blah = 'Some text'example.last_set #=> "Some text"example.some_method # prints "5"example.last_set #=> "Some text"


查看完整回答
反对 回复 2019-06-11

添加回答

回复

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信