I am accessing model Company::Item in controller Security::MyController. It is giving error uninitialised constant Security::Company::Item . So basically it is appending 'Security::' for given model. It is not the case with some other models say Security::User(model in same module security). What could be possible explanation for this?
This is a scope resolution problem. You should try using ::Company::Iteminside Security::MyController
According to Ruby Language Spec
::Something is a shortcut for Object::Something. The idea is that ::Something
should look up a constant called Something in the global scope, but since ruby
doesn't truly have a global scope, it looks it up in the Object class, which is
the nearest thing in ruby to a global scope.
Prefixing :: will prevent Ruby from applying the default scope in that context, which in your case, is the Security:: scope
Related
An important part of OOP is to use access specifiers to make member methods and variables inaccessible from outside of the object.
When declaring a function block method is is easy to control the Access Specifier, but I have not found a way to control access to member variables.
Is it possible and if yes, how?
You can actually still access internal variables of an object direcly in code (no pointers), but they are read only. The code completion will not display the internal variables though, but after you finish typing the name structure, you will see no compile errorrs - test := fb1.internalVariable will be a valid read action actually while fb1.internalVariable := 5; will end up giving you an error, saying that the variable is not an input to the function block (or any other object for that matter).
You can also use the hide oder hide_all_locals pragma to suppress local variables being found in auto-complete and crossreference-list (see https://infosys.beckhoff.com/content/1033/tc3_plc_intro/2529654667.html?id=5927203996458905204 )
Every variable that you declare under the VAR section of your Function Block is considered private.
There is no public or private keyword for variables in IEC 61131-3
Another thing you can do if you absolutely want to use public/private keywords is to define properties.
In general, the normal convention is to have read-only variables in the VAR_OUTPUT section of the Function Block and writable variables in the VAR_INPUT section of the Function Block. Again, the VAR section is considered a private section even though you could read this variables with the fbName.var notation or write them through their address (but this is a very bad programming style).
Twincat2 also allowed the variables in the VAR section to be written to with the fbName.var notation but this changed in Twincat3 in order to achieve better incapsulation.
To learn more about programming conventions in the IEC 61131-3 world, I recommend you to read the programming guidelines of the PLCOpen organization:
https://plcopen.org/guidelines/guidelines
I'm new to elixir and phoenix and I wanted to doctest a newly created context (using mix phx.gen.context).
I have an Accounts context with a User schema.
I added to accounts_test.exs the following lines:
alias MyApp.Accounts.User
doctest MyApp.Accounts.User, import: true
And even fixed the default change_user documentation:
- %Ecto.Changeset{source: %User{}}
+ %Ecto.Changeset{data: %User{}}
But I still have many, many, errors and warnings, as if it was basically not made to be doctested...
For example, the default generated doc puts:
iex> update_user(user, %{field: new_value})
{:ok, %User{}}
This would issue:
warning: variable "new_value" does not exist and is being expanded to "new_value()"...
warning: variable "user" does not exist and is being expanded to "user()"...
test/my_app/accounts_test.exs:45: undefined function new_value/0
test/my_app/accounts_test.exs:45: undefined function user/0
My question is: is there something I'm missing? Or is it generally not common to doctest one's context (which would explain why it doesn't work out-of-the-box)
Generally speaking we do not doctest functions that have side-effects, such as context functions that have to read/write to the database, because they would require some amount of setup that is hard to cleanly portray in the doctest itself.
It is certainly doable but you should ask yourself if it is worth the effort. The Phoenix team itself seems to think it isn't. :)
In Rails, when we define Global Variable(i.e. in Application.rb file), it is Constant and we can't modifiy it. Is there any alternate available in Rails that i can use the Variable as Global variable in my Rails application and access and change it's value during execution ?
This may not be exactly what you are looking for, but you could put a function in your ApplicationController that sets a variable, then set up a before_filter :your_def. Set your variable up as an #variable and then have access/edit it any controller.
While modifying an existing program's CASE statement, I had to add a second block where some logic is repeated to set NetWeaver portal settings. This is done by setting values in a local variable, then assigning that variable to a Changing parameter. I copied over the code and did a Pretty Print, expecting to compiler to complain about the unknown variable. To my surprise however, this code actually compiles just fine:
CASE i_actionid.
WHEN 'DOMIGO'.
DATA: ls_portal_actions TYPE powl_follow_up_sty.
CLEAR ls_portal_actions.
ls_portal_actions-bo_system = 'SAP_ECC_Common'.
" [...]
c_portal_actions = ls_portal_actions.
WHEN 'EBELN'.
ls_portal_actions-bo_system = 'SAP_ECC_Common'.
" [...]
C_PORTAL_ACTIONS = ls_portal_actions.
ENDCASE.
As I have seen in every other programming language, the DATA: declaration in the first WHEN statement should be encapsulated and available only inside that switch block. Does SAP ignore this encapsulation to make that value available in the entire CASE statement? Is this documented anywhere?
Note that this code compiles just fine and double-clicking the local variable in the second switch takes me to the data declaration in the first. I have however not been able to test that this code executes properly as our testing environment is down.
In short you cannot do this. You will have the following scopes in an abap program within which to declare variables (from local to global):
Form routine: all variables between FORM and ENDFORM
Method: all variables between METHOD and ENDMETHOD
Class - all variables between CLASS and ENDCLASS but only in the CLASS DEFINITION section
Function module: all variables between FUNCTION and ENDFUNCTION
Program/global - anything not in one of the above is global in the current program including variables in PBO and PAI modules
Having the ability to define variables locally in a for loop or if is really useful but unfortunately not possible in ABAP. The closest you will come to publicly available documentation on this is on help.sap.com: Local Data in the Subroutine
As for the compile process do not assume that ABAP will optimize out any variables you do not use it won't, use the code inspector to find and remove them yourself. Since ABAP works the way it does I personally define all my variables at the start of a modularization unit and not inline with other code and have gone so far as to modify the pretty printer to move any inline definitions to the top of the current scope.
Your assumption that a CASE statement defines its own scope of variables in ABAP is simply wrong (and would be wrong for a number of other programming languages as well). It's a bad idea to litter your code with variable declarations because that makes it awfully hard to read and to maintain, but it is possible. The DATA statements - as well as many other declarative statements - are only evaluated at compile time and are completely ignored at runtime. You can find more information about the scopes in the online documentation.
The inline variable declarations are now possible with the newest version of SAP Netweaver. Here is the link to the documentation DATA - inline declaration. Here are also some guidelines of a good and bad usage of this new feature
Here is a quote from this site:
A declaration expression with the declaration operator DATA declares a variable var used as an operand in the current writer position. The declared variable is visible statically in the program from DATA(var) and is valid in the current context. The declaration is made when the program is compiled, regardless of whether the statement is actually executed.
Personally have not had time to check it out yet, because of lack of access to such system.
Currently I have repeated code in multiple modules something like this:
def do_something_polymorphic
self.something_polymorphic_able.where(.....).each do |thing|
...
end
end
In the spirit of DRY, I tried moving do_something_polymorphic() into a module at /lib/shared_methods.rb. When I added include SharedMethods in my models I got an error:
uninitialized constant Chapter::SharedMethods (NameError)
Which I could not figure out how to get around.
Then I tried loading the module file into the models (load 'shared_methods.rb'). It loaded OK, but the Module construct threw off the namespace and do_something_polymorphic() was undefined for the model in which it was loaded/included. So "Module" appears not to be an option if you are trying to self-reference an object.
Lastly, I removed the module construct from the shared_methods.rb file and just left the do_something_polymorphic() method alone in the file. It loaded OK, but when I ran the method I got the error:
NoMethodError: private method `do_something_polymorphic' called for #<Polymorphic_Object:0x007fc27e5b8338>
Not sure where to go from here. I could go back to setting this up as a module and try to pass "self" in as an object parameter to the method, but I would like to preserve the ability to cleanly call the method against its object: current_object.do_something_polymorphic
Short of going the inheritance route (which I really want to avoid,) is there a way to share, across multiple models, a method that uses the self keyword?
You can include lib/ modules automatically by modifying the application configuration.
#config/application.rb
config.autoload_paths += %W(#{config.root}/lib)