Julia - REPL doesn't update module variable after modifying module's code - compilation

EDIT: In the end it had nothing to do with it. I'm answering for anyone in a similar situation.
I discovered Julia a month ago and have been fascinated with it since then.
However, it seems compilation (or a variable scope) is still not clear for me.
I have this module in plots.jl:
module plottinghhkp
instance_path = "somestring"
function dosomething()
...
end
...
end
and then include it in the REPL to run module functions
julia> include("plots.jl")
...
julia> hhkplot.instance_path
julia> "somestring"
I then modify instance_path, and re-import using include again, but instance_path shows old value instead of the new value:
julia> include("plots.jl")
...
julia> plottinghhkp.instance_path
"somestring"
My solution was to rename the variable to instancepath so that a new symbol is created, however, autocomplete now shows:
julia> plottinghhkp.
instance_path instancepath
julia> plottinghhkp.instancepath
"newvalue"
julia> plottinghhkp.instance_path
"somestring"
when the instance_path symbol does not exist anymore in the module.
Creating a fresh environment with workspace() never ends.
Why is this happening? Do I need to explicitly load Julia with no precompiling, or add __precompile__(false) to the module? Or is it something about the variable scopes?
Thanks.

I managed to solved the problem. Of course, it had nothing to do about compilation. It was a namespace problem. There were two variables under the same name, but each had a different namespace since one of them was wrapped around a module.
If you come across a similar situation, be sure to look at all your modules/namespaces. Working with different namespaces would be ideal so you don't have any clashes.

Related

Convert Strings to Class Names in ruby

I am trying to write a script in ruby which involves converting a string to Class Names. Since I am using pure ruby I cannot use .constantize.
I have tried using Object.const_get('String') but not sure why it is throwing a uninitialized constant String (NameError)
I have require 'active_support' on the top of the file
The conventional way of assigning a name to an anonymous class is as follows.
bub = Class.new do
def b
'hi'
end
end
str = 'Bubba'
Object.const_set(str, bub)
Bubba.is_a?(Class)
#=> true
Bubba.new.b
#=> "hi"
Is that what you want to do? If so, as you see, you need to use Module#const_set.
Do you try to use const_get only for a class or it is under a namespace like ModuleA::ModuleB::ClassName?
Also converting a string to a class name makes a new class or assigns the value to it?
I am asking these questions because the answer will affect the method you have to use. Maybe const_set instead of const_get is the correct approach, I don't know.
From the comments you gave it looks like 'String' is just an example and not the value that you literally pass to const_get. The actual value apparently is 'Assignment', is this correct?
When you execute Object.const_get('Assignment') and you receive the uninitialized constant error it indicates that at this point the class Assignment has not been loaded yet.
When you are using Rails then a lot of autoloading takes place if the files are in the right folder and the classes follow the naming conventions. Since you are running a "standalone" ruby script, autoloading does not take place and you will need to load the file yourself.
Adding a line like
require_relative "somepath/assignment"
should work. somepath needs to be adapted to the directory/file layout you have. It will load the file and execute the ruby code in that file.
If assignment.rb defines something like
class Assignment
end
Then the const_get will work.
That being said: what is your exact use case for this? Why do you need to dynamically find classes? Also Note that this opens up your app to (an unlikely) potential security issues if you let user input define what classes are loaded.

Perl, Alias sub to variable

I'm currently doing micro-optimization of a perl program and like to optimize some getters.
I have a package with this getter-structure:
package Test;
our $ABC;
sub GetABC { $ABC } # exported sub...
Calling GetABC() creates a lot of sub-related overhead. Accessing the variable directly via $Test::ABC is insanely faster.
Is there a way to alias the getter to the variable to gain the same performanceboost as if I would call the variable directly? Inlining hint with "()" doesn seem to work...
There is no way to turn a variable into an accessor sub, or to replace a sub with a variable access. You will have to live with the overhead.
Non-solutions:
Using a () prototype does not turn calls into your sub to constant accesses because that prototype merely makes a sub potentially eligible for inlining. Since the body of the sub is not itself constant, this sub cannot be a constant.
The overhead is per-call as perl has to do considerable bookkeeping for each call. Therefore, rewriting that accessor in XS won't help much.
Creating a constant won't help because the constant will be a copy, not an alias of your variable.
But looking at the constant.pm source code seems to open up an interesting solution. Note that this a hack, and may not work in all versions of Perl: When we assign a scalar ref to a symbol table entry directly where that entry does not yet contain a typeglob, then an inlineable sub springs into place:
package Foo;
use strict;
use warnings;
use feature 'say';
my $x = 7;
BEGIN { $Foo::{GetX} = \$x } # don't try this at home
say GetX; #=> 7
$x = 3;
say GetX; #=> 3
This currently works on most of my installed perl versions (5.14, 5.22, 5.24, 5.26). However, my 5.22-multi and 5.26-multi die with “Modification of a read-only value attempted”. This is not a problem for the constant module since it makes the reference target readonly first and (more importantly) never modifies that variable.
So not only doesn't this work reliably, this will also completely mess up constant folding.
If the function call overhead is indeed unbearable (e.g. takes a double-digit percentage of your processing time), then doing the inlining yourself in the source code is going to be your best bet. Even if you have a lot of call locations, you can probably create a simple script that fixes the easy cases for you: select all files that import your module and only have a single package declaration. Within such files, replace calls to GetABC (with or without parens) to fully qualified variable accesses. Hopefully that token is not mentioned within any strings. Afterwards, you can manually inspect the few remaining occurrences of these calls.

Defining and using constants inside Rspec's hooks

I am kinda of new to Rspec and I am writing some test examples when a question came up.
First, I was using global variables to define three constant values I was going to use in a lot of tests. For example:
$message = 'this is a test'
However, I notice that this global was being carried over to other test files and causing issues. Ok... decided then to avoid the globals as this can cause a lot of pain in the future in case my test file number grows.
I then went for the let() block. Example:
let(:message) { 'this is a test' }
Now the problem was that this variable could not be used inside before and after hooks. Ok...
My last try was using constants inside the contexts/describes, like this:
self::MESSAGE = 'this is a test'
However, just like let's this cannot be used inside the hooks as they are not either classes or modules.
So, I am stuck ...
How do you guys deal with that? Will I need to create instance variables for that? Is that any other alternative I can use?
Thank you very much.
You have one other option for defining data -- instance variables.
before do
#data = [ {one: 1, two: 2},
{one: 2, two: 3} ]
end
You can use #data in all the tests within the scope of the before. This is pretty much the same as let for the purposes of just setting up static data, but it might be a better fit for you -- without seeing your code it's hard to say.

Access local variables from a different binding in Ruby

In Ruby, you can easily access local variables programmatically by using local_variables and eval. I would really like to have meta-programming access to these variables using a single method call such as
# define a variable in this scope, such as
x = 5
Foo.explore_locals # inside the Foo#explore_locals method, access x
where Foo is some external module. The idea is to display and export local variables in a nice way.
What should be inside the explore_locals method? Is there any way to make this possible? If absolutely necessary, I guess it could be
Foo.explore_locals binding
but this is much less elegant for the application I have in mind.
It's a shame there isn't a built-in way to get the caller's binding. The block trick seems to be the usual answer to this question.
However there is another 'trick' which existed for older 1.8 Ruby versions called binding_of_caller. Looks like quix ported it to 1.9. You might want to check that out:
https://github.com/quix/binding_of_caller
Here is an example (but it requires extra braces {} which I would rather avoid if possible):
module Foo
def self.explore_locals &block
p block.binding.eval 'local_variables'
end
end
local_1 = 3
Foo.explore_locals{} # shows [:local_1, :_]

Ruby: Setting a global variable by name

I am trying to dynamically set (not create, it already has to exist) a global ruby variable in a method. The variable name is determined from the passed symbol. What I am currently doing is the following:
def baz(symbol)
eval("$#{symbol}_bar = 42")
end
$foo_bar = 0
baz(:foo)
puts $foo_bar # => 42
But to me, this kind of feels very wrong. Is this the way to do this? Or can it be done differently? Also, I don't know how evals perform in ruby. Does it run much slower than
$foo_bar = 42
The method looks fine to me. This guy says that eval efficiency is much worse, though the post is 3 years old.
I will point out that this method suggests you have a lot of global variables, which is generally a code smell if the code base is significant.
If you can use an instance variable instead, there is Object#instance_variable_set.
def baz(symbol)
instance_variable_set("##{symbol}_bar", 42)
end
Note that it only accepts variable names that can be accepted as an instance variable (starting with #). If you put anything else in the first argument, it will return an error. For the global variable counterpart to it, there is a discussion here: Forum: Ruby
Either way, you also have the problem of accessing the variable. How are you going to do that?

Resources