Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

stub_const doesn't work with constant inside class << self block #1536

Open
s101d1 opened this issue Mar 10, 2023 · 3 comments
Open

stub_const doesn't work with constant inside class << self block #1536

s101d1 opened this issue Mar 10, 2023 · 3 comments

Comments

@s101d1
Copy link

s101d1 commented Mar 10, 2023

I'm not sure if this is a bug or not, I found out the stub_const doesn't work with constant inside class << self block.

class HelloWorld

    class << self
        FOO = "hello"
    end

end

describe HelloWorld do 
    context "Testing the HelloWorld" do 

        it "testing" do 
            p HelloWorld.singleton_class::FOO   # print "hello"
            stub_const("HelloWorld.singleton_class::FOO", "world")  # error at here
            p HelloWorld.singleton_class::FOO   # expected to print "world" at here if there is no error
        end

   end
end

The stub_const("HelloWorld.singleton_class::FOO", "world") line gives this error:

 Failure/Error: stub_const("HelloWorld.singleton_class::FOO", "world")
 
 NameError:
   wrong constant name HelloWorld.singleton_class
 
             mod.const_defined?(const_name, false)

Is there a workaround other than moving the FOO = "hello" outside the class << self block?

@JonRowe
Copy link
Member

JonRowe commented Mar 12, 2023

This isn't a bug so much, more of a lack of feature, HelloWorld.singleton_class returns a class, not a constant name, and stub_const takes a string representing a constant name, so the two apis are incompatible, we don't evaluate the string but use it to find the constant and replace it via the Ruby api's for doing so.

It's probably possible to expand the api to cope with this scenario if you wanted to tackle it, I'm a bit unsure if we'd want to but I'm open to discussing that further...

I'm sort of curious why you even want to define a constant within the singleton class, that seems a bit unusual and very much an edge case?

@s101d1
Copy link
Author

s101d1 commented Mar 12, 2023

I'm sort of curious why you even want to define a constant within the singleton class, that seems a bit unusual and very much an edge case?

I was creating a module actually (the "HelloWorld" class in above example is actually a module in the real case). So it looks something like this:

module HelloWorld

    class << self
        FOO = ...

    end

    # OtherClass and OtherClass2 don't use the FOO constant at all
    class OtherClass
        ...
    end
    
    class OtherClass2
    	...
    end
end

Since the FOO constant is only used by the methods inside the class << self block, I feel it more makes sense to define the constant inside the class << self rather than on the module level.

@JonRowe
Copy link
Member

JonRowe commented Mar 12, 2023

If you used module_function to create functions on HelloWorld you'd have access to HelloWorld::FOO

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants