简体   繁体   English

如何从另一个包含的模块中访问包含的模块的方法?

[英]How to access an included module's methods from within another included module?

module Foo
  attr_accessor :val
end

module Bar
  def bar
    val = 50
  end
end

class FooBar
  include Foo
  include Bar
end

fb = FooBar.new
puts fb.bar # 50
puts fb.val # nil

I would like to, from within Bar, change Foo's "val" value. 我想从Bar内更改Foo的“ val”值。

Just so you know, I'm trying to do this because I want to add user authentication through a Facebook Canvas app in Clearance (0.8.2 (old, I know)). 请注意,我正在尝试执行此操作,因为我想通过Clearance(0.8.2(我知道,很旧))中的Facebook Canvas应用添加用户身份验证。 The variable that I want to change is https://github.com/thoughtbot/clearance/blob/b8ccca00d91cb336e044b76b5c6ae1d8de9d2d8d/lib/clearance/authentication.rb#L25 . 我要更改的变量是https://github.com/thoughtbot/clearance/blob/b8ccca00d91cb336e044b76b5c6ae1d8de9d2d8d/lib/clearance/authentication.rb#L25

This module gets included into ApplicationController, and I'm including another module afterwards (FacebookAuthenticationHelper) that does something like 该模块已包含在ApplicationController中,此后我还要添加另一个模块(FacebookAuthenticationHelper),该模块的功能类似于

def authenticate_facebook
  current_user ||= facebook_user if coming_from_facebook?
end

I would love to know if there's a better way to do this as well. 我很想知道是否还有更好的方法可以做到这一点。 I'm not using OAuth, I'm just saving Facebook's user_id sends to my app from signed_request into my DB. 我没有使用OAuth,只是将Facebook的user_id从signed_request发送到我的应用程序保存到数据库中。

Thanks! 谢谢!

In ruby, any statement of the form varname = value will create a local variable named varname if it doesn't already exist. 在ruby中,任何形式为varname = value语句都会创建一个名为varname的局部变量(如果尚不存在)。 This is even true within class methods where the class has a setter method of the same name. 在类方法中,甚至在类具有相同名称的setter方法的情况下,也是如此。 Furthermore, if a local variable exists, it takes precedence over getters and setters. 此外,如果存在局部变量,则该变量优先于getter和setter。 For example: 例如:

class Demo
    attr_accessor :foo

    def demonstrate!
        @foo = 1      #1: Set member variable foo, so we get meaningful output
        puts foo      #2: Prints 1 (this calls the getter)
        puts self.foo #3: Prints 1 (also calls the getter)

        foo = 2       #4: Creates a LOCAL variable named foo with the value 2
        puts foo      #5: Prints 2 (locals take precedence over getters)
        puts self.foo #6: Prints 1 (calls the getter - the member variable hasn't changed)

        self.foo = 3  #7: Use SELF to ensure you call a getter or setter
        puts foo      #8: Prints 2 (the local again)
        puts self.foo #9: Prints 3 (the member, which is now 3)
    end
end

The bad thing about this system is: Look at lines 2 and 5. The same exact code does different things! 这个系统的坏处是:看第2行和第5行。相同的确切代码执行不同的操作! On line 2, the local variable foo didn't exist yet, so ruby did the "next best" thing and called the getter. 在第2行,本地变量foo还不存在,因此ruby做了“次佳”的事情,并将其称为getter。 But on line 5, the local foo exists, so it takes precedence. 但是在第5行,本地foo存在,因此它具有优先权。

I'd say that this is bad language design: If setters can't be called without self , why should it be okay for getters - especially when it can lead to rickety, context-sensitive code like the above? 我会说这是不好的语言设计:如果不能在没有self情况下调用setter,为什么对getter来说还可以-尤其是当它会导致像上面那样摇摇欲坠,上下文相关的代码时? But it's what we have to work with, and it leads to some general guidelines: 但这是我们必须使用的内容,它导致了一些通用准则:

  1. If you can, use @foo . 如果可以,请使用@foo It's obvious what that does. 很明显这是做什么的。
  2. If you're using a getter or setter, always use self , even when it's not strictly necessary. 如果您使用的是getter或setter方法,则即使不是绝对必要,也请始终使用self This makes it obvious what you're calling. 这使您在说什么变得很明显。 It also guarantees your code won't behave differently if you add a local with the same name later. 如果以后添加具有相同名称的本地语言,它还可以确保您的代码不会有不同的行为。
  3. If you do 1 and 2, you can assume that anything without a @ or a self is a local variable (or a function call, but you can probably tell those apart by name). 如果执行1和2,则可以假定没有@self任何内容都是局部变量(或函数调用,但是您可以按名称区分它们)。

And that ended up being a bit long-winded, but I was unable to find a good demonstration of the getter/setter/local problem to link to. 最终结果有些冗长,但是我找不到链接到的getter / setter / local问题的良好演示。 So maybe this is it - hope it's helpful! 所以也许就这样-希望对您有所帮助!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM